• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            洗塵齋

            三懸明鏡垂鴻韻,九撩清泉洗塵心

            常用鏈接

            統(tǒng)計(jì)

            最新評(píng)論

            信號(hào)量與PV操作

            //信號(hào)量與PV操作的一個(gè)例子,模擬借書還書操作,共4個(gè)用戶,每用戶最多借15本書,書庫共40本書,在書庫沒書時(shí),該用戶處于睡眠等待狀態(tài),直到有其他用戶還書,若所有用戶均處于等待狀態(tài),則產(chǎn)生了死鎖

            int Semget(key_t semkey,int nsems,int semflgs);
            bool P(int sid,int semnum,int n);
            bool V(int sid,int semnum,int n);
            void sig_usr1(int);
            static int pid[4];
            int main(int argc,char **argv)
            {
                
            int semid;
                
            if((semid=Semget(4446,1,IPC_CREAT|IPC_EXCL|0666))==-1)exit(-1);
                
            if(semctl(semid,0,SETVAL,40)==-1)perr_exit("semctl");   //書的總量

                
            int book,sleeptime;
                
            int borrow;
                
            for(int i=0;i<4;i++){      //4個(gè)用戶
                    pid[i]
            =fork();
                    
            if(pid[i]<0){perror("Fork");i--;}
                    
            else if(pid[i]==0){
                        srand(time(NULL)
            +i);
                        book
            =0;
                        
            while(1){
                            sleeptime
            =rand()%7;
                            borrow
            =sleeptime-3;   //每次最多借還3本
                            
            if(borrow>0&&borrow+book<=15)   //每人最多借15本
                            {
                                
            if(!P(semid,0,borrow))
                                    
            continue;
                                book
            +=borrow;
                                cout
            <<"User "<<i<<" borrow "<<borrow<<" books from libary,"
                                    
            <<"now it remains ";
                                
                                cout
            <<semctl(semid,0,GETVAL,0)<<" books\n";
                                sleep(sleeptime);
                            }
                            
            else if(borrow<0&&borrow+book>=0)
                            {
                                
            if(!V(semid,0,-borrow))continue;
                                book
            +=borrow;
                                cout
            <<"User "<<i<<" gives "<<-borrow<<" books back to libary,"
                                    
            <<"now it remains ";   //由于V與GETVAL并不是原子操作,此處可能打印錯(cuò)誤
                                                            //有可能在歸還與取值之間,書被借出
                                
                                cout
            <<semctl(semid,0,GETVAL,0)<<" books\n";
                                
                                sleep(sleeptime);
                            }
                        }
                        
            return 0;
                    }
                }
                signal(SIGUSR1,sig_usr1);
                
            while(1)usleep(1000);
                
            return 0;
            }

            int Semget(key_t semkey,int nsems,int semflgs)
            {
                
            int semid;
                
            if ((semid = semget(semkey, 00)) == -1) {  /* Semaphore does not exist - Create. */
                    
            if ((semid = semget(semkey,nsems,semflgs)) != -1)
                        
            return semid;
                    
            else if (errno == EEXIST) {
                        
            if((semid = semget(semkey, 00)) == -1) {
                            perror(
            "IPC error 1: semget"); return -1;
                        }
                    }
                    
            else {
                        perror(
            "IPC error 2: semget"); return -1;
                    }
                }
                
            return semid;
            }

            void sig_usr1(int sig)
            {
                
            for(int i=0;i<4;i++)
                    kill(pid[i],SIGQUIT);
                kill(getpid(),SIGQUIT);
            }

            bool Semset(int sid,int semnum,int n)
            {
                
            struct sembuf sm;
                sm.sem_num
            =semnum;
                sm.sem_op
            =n;
                sm.sem_flg
            =SEM_UNDO;
                
            if(semop(sid,&sm,1)==-1){
                    perror (
            "semop");
                    
            return false;
                }
                
            return true;
            }

            bool P(int sid,int semnum,int n)
            {
                
            return Semset(sid,semnum,-n);
            }

            bool V(int sid,int semnum,int n)
            {
                
            return Semset(sid,semnum,n);
            }

            以下是解決死鎖之后的代碼,主進(jìn)程負(fù)責(zé)監(jiān)測子進(jìn)程,如果發(fā)生死鎖,就發(fā)信號(hào)阻止某個(gè)進(jìn)程,禁止其消費(fèi),只允許其生產(chǎn),而若該子進(jìn)程不能生產(chǎn),則用信號(hào)通知父進(jìn)程,讓其另選其他進(jìn)程阻止。而若子進(jìn)程監(jiān)測到資源可供消費(fèi),則向自身發(fā)信號(hào),設(shè)置其為可消費(fèi)狀態(tài)。
            int Semget(key_t semkey,int nsems,int semflgs);
            bool P(int sid,int semnum,int n);
            bool V(int sid,int semnum,int n);
            void sig_usr1(int);
            void sig_usr2(int);
            #define MaxUser 5
            static int pid[MaxUser];
            volatile bool good=true;
            static int lastdeny;
            static int user;
            #define SIGDENY    SIGUSR2+1
            #define SIGALLOW    SIGUSR2
            #define SIGNEXTDENY    SIGUSR2+2
            int main(int argc,char **argv)
            {
                
            int semid;
                
            if((semid=Semget(4446,1,IPC_CREAT|IPC_EXCL|0666))==-1)exit(-1);
                
            if(semctl(semid,0,SETVAL,40)==-1)perr_exit("semctl");

                
            int book,sleeptime;
                
            int borrow;
                
            for(user=0;user<MaxUser;user++){
                    pid[user]
            =fork();
                    
            if(pid[user]<0){perror("Fork");user--;}
                    
            else if(pid[user]==0){
                        srand(time(NULL)
            +user);
                        book
            =0;
                        signal(SIGALLOW,sig_usr2);
                        signal(SIGDENY,sig_usr2);
                        
            while(1){
                            sleeptime
            =rand()%6;
                            borrow
            =sleeptime-2;
                            
            if(!good &&semctl(semid,0,GETNCNT,0)<MaxUser-1)
                                kill(getpid(),SIGALLOW);
                            
            else if(borrow>0&&borrow+book<=15&&good)
                            {
                                
            if(!P(semid,0,borrow))
                                    
            continue;
                                book
            +=borrow;
                                cout
            <<"User "<<user <<" borrow "<<borrow<<" books from libary,"
                                    
            <<"now it remains ";
                                
                                cout
            <<semctl(semid,0,GETVAL,0)<<" books\n";
                                sleep(sleeptime);
                            }
                            
            else if(borrow<0&&borrow+book>=0)
                            {
                                
            if(!V(semid,0,-borrow))continue;
                                book
            +=borrow;
                                cout
            <<"User "<<user<<" gives "<<-borrow<<" books back to libary,"
                                    
            <<"now it remains ";
                                
                                cout
            <<semctl(semid,0,GETVAL,0)<<" books\n";
                                
                                sleep(sleeptime);
                            }
                            
            else if(!good&&book==0)    //cannot borrow and no book keeping
                            {
                                kill(getpid(),SIGALLOW);
                                kill(getppid(),SIGNEXTDENY);    
            //send signal to parent to deny some other user
                            }

                        }
                        
            return 0;
                    }
                }
                signal(SIGUSR1,sig_usr1);
                signal(SIGNEXTDENY,sig_usr2);
                srand(time(NULL));
                
            volatile int x=0;
                
            int y=0;

                
            while(1){        
                    
            if(semctl(semid,0,GETNCNT,0)>=MaxUser){    //deadlock appear
                        while(pid[(x=rand()%MaxUser)]==lastdeny);
                        kill((lastdeny
            =pid[x]),SIGDENY);        //make some user cannot borrow
                    }
                    usleep(
            1000);
                    y
            ++;
                    
            if(y%1000==0){
                        y
            =0;
                        cout
            <<"\t\tMain Running\t\t"<<semctl(semid,0,GETNCNT,0)<<"waits\n";
                    }
                }
                
            return 0;
            }

            int Semget(key_t semkey,int nsems,int semflgs)
            {
                
            int semid;
                
            if ((semid = semget(semkey, 00)) == -1) {  /* Semaphore does not exist - Create. */
                    
            if ((semid = semget(semkey,nsems,semflgs)) != -1)
                        
            return semid;
                    
            else if (errno == EEXIST) {
                        
            if((semid = semget(semkey, 00)) == -1) {
                            perror(
            "IPC error 1: semget"); return -1;
                        }
                    }
                    
            else {
                        perror(
            "IPC error 2: semget"); return -1;
                    }
                }
                
            return semid;
            }

            void sig_usr1(int sig)
            {
                
            for(int i=0;i<MaxUser;i++)
                    kill(pid[i],SIGQUIT);
                kill(getpid(),SIGQUIT);
            }

            void sig_usr2(int sig)
            {
                
            if(sig==SIGALLOW){        //allow user  borrow book
                    good=true;
                    cout
            <<"/*--------------------------User"<<user
                        
            <<" Allowed-----------------------*/"<<endl;
                }
                
            else if(sig==SIGDENY){    //deny user borrow book
                    good=false;
                    cout
            <<"/*---------------------------User"<<user
                        
            <<" Denied-----------------------*/"<<endl;
                }
                
            else if(sig==SIGNEXTDENY){    //deny some user
                    volatile int deny;
                    
            while(pid[deny=rand()%MaxUser]==lastdeny);
                    kill((lastdeny
            =pid[deny]),SIGDENY);
                }
            }

            bool Semset(int sid,int semnum,int n)
            {
                
            struct sembuf sm;
                sm.sem_num
            =semnum;
                sm.sem_op
            =n;
                sm.sem_flg
            =SEM_UNDO;
                
            if(semop(sid,&sm,1)==-1){
                    cout
            <<"/**********User "<<user<<" semop error:"
                        
            <<strerror(errno)<<"**************/"<<endl;
                    
            return false;
                }
                
            return true;
            }

            bool P(int sid,int semnum,int n)
            {
                
            return Semset(sid,semnum,-n);
            }

            bool V(int sid,int semnum,int n)
            {
                
            return Semset(sid,semnum,n);
            }

            posted on 2007-09-20 14:21 芥之舟 閱讀(5268) 評(píng)論(1)  編輯 收藏 引用 所屬分類: unix

            評(píng)論

            # re: 信號(hào)量與PV操作 2009-03-04 16:16 0019B0

            bool P(int sid,int semnum,int n)
            {
            return Semset(sid,semnum,-n);
            }

            bool V(int sid,int semnum,int n)
            {
            return Semset(sid,semnum,n);
            }











              回復(fù)  更多評(píng)論   

            99国产精品久久久久久久成人热| 久久99精品综合国产首页| 麻豆精品久久久久久久99蜜桃| 国内精品久久人妻互换| 老男人久久青草av高清| 久久精品国产精品亚洲毛片| 国产精品久久久久免费a∨| 国产精品一区二区久久不卡| 久久久久无码国产精品不卡| 99国内精品久久久久久久| 国内精品久久久久久99| 少妇被又大又粗又爽毛片久久黑人| 久久九色综合九色99伊人| 久久综合国产乱子伦精品免费| 亚洲日韩中文无码久久| 伊人色综合久久天天人手人婷| 久久亚洲国产欧洲精品一| 国产69精品久久久久99| 久久久久女教师免费一区| 波多野结衣中文字幕久久| 亚洲人成伊人成综合网久久久| 久久综合九色综合欧美就去吻| 一本久久a久久精品综合香蕉| 久久久久久精品免费看SSS| 亚洲伊人久久大香线蕉综合图片| 久久婷婷人人澡人人| 色综合合久久天天综合绕视看| 久久婷婷五月综合97色一本一本| 久久久一本精品99久久精品88| 久久久久无码国产精品不卡| 久久成人18免费网站| 热99RE久久精品这里都是精品免费| 国产精品午夜久久| 日韩中文久久| 久久精品人人做人人爽电影| 欧美伊人久久大香线蕉综合| 久久婷婷国产剧情内射白浆| 久久中文字幕人妻熟av女| 久久WWW免费人成一看片| 欧美噜噜久久久XXX| 久久精品亚洲精品国产色婷 |