• <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)計

            最新評論

            信號量與PV操作

            //信號量與PV操作的一個例子,模擬借書還書操作,共4個用戶,每用戶最多借15本書,書庫共40本書,在書庫沒書時,該用戶處于睡眠等待狀態(tà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);
            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個用戶
                    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并不是原子操作,此處可能打印錯誤
                                                            //有可能在歸還與取值之間,書被借出
                                
                                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);
            }

            以下是解決死鎖之后的代碼,主進程負責監(jiān)測子進程,如果發(fā)生死鎖,就發(fā)信號阻止某個進程,禁止其消費,只允許其生產,而若該子進程不能生產,則用信號通知父進程,讓其另選其他進程阻止。而若子進程監(jiān)測到資源可供消費,則向自身發(fā)信號,設置其為可消費狀態(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 芥之舟 閱讀(5267) 評論(1)  編輯 收藏 引用 所屬分類: unix

            評論

            # re: 信號量與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);
            }











              回復  更多評論   

            久久久久久毛片免费看| 久久国产乱子精品免费女| 久久综合久久伊人| 精产国品久久一二三产区区别| 久久国产AVJUST麻豆| 99国产欧美久久久精品蜜芽 | 久久香综合精品久久伊人| 久久精品国产亚洲αv忘忧草| 72种姿势欧美久久久久大黄蕉| 99久久精品免费看国产一区二区三区| 伊人色综合九久久天天蜜桃| AV无码久久久久不卡蜜桃| 伊人久久大香线蕉综合热线| 看久久久久久a级毛片| 亚洲精品99久久久久中文字幕| 久久精品国产第一区二区三区| 污污内射久久一区二区欧美日韩| 97久久精品午夜一区二区| 亚洲午夜久久久影院| 亚洲国产成人精品无码久久久久久综合| 久久A级毛片免费观看| 亚洲午夜久久久久久久久电影网 | 91精品国产91久久久久久青草| 伊人久久国产免费观看视频| 精品久久久久久无码国产| avtt天堂网久久精品| 777午夜精品久久av蜜臀| 无码8090精品久久一区| 精品久久久久一区二区三区| 国产精品VIDEOSSEX久久发布| 国产产无码乱码精品久久鸭| 久久久久亚洲av无码专区喷水 | 久久久精品波多野结衣| 精品免费tv久久久久久久| 久久综合九色综合网站| 久久精品天天中文字幕人妻| 久久久久久亚洲精品成人| 久久久久免费看成人影片| 狠狠色婷婷综合天天久久丁香| 国产V综合V亚洲欧美久久| 亚洲一本综合久久|