读者---写者问题
經典進程同步與互斥問題
讀者---寫者問題
1.問題描述
一個數據對象若被多個并發進程所共享,且其中一些進程只要求讀該數據對象的內容,而另一些
進程則要求寫操作,對此,把只想讀的進程稱為“讀者”,而把要求寫的進程稱為“寫者”。在
讀者--寫著問題中,任何時刻要求“寫者”最多只允許有一個,而讀者則允許有多個。因為多個
讀者的行為互不干擾,他們只是讀數據,而不改變數據對象的內容,而寫者則不同,他們要改變數據對象的內容,如果他們同時操作,則數據對象的內容將會改變的不可知。所以對共享資源的讀寫操作的限制條件是:
1>允許任意多的讀進程同時讀;
2>一次只允許一個寫進程寫操作;
3>如果有一個寫進程正在進行寫操作,禁止任何讀進程進行讀操作。
2.用信號量解決讀者--寫著問題
為了解決“寫著與寫著”和“寫著與第一個讀者”的互斥問題即可,為此引入互斥信號量Wmutex。
為了記錄誰是第一個讀者,可以用一個全局整型變量Rcount做一個計數器。而在解決問題的過程中,由于使用了全局變量Rcount,該變量又是一個臨界資源,對于他的訪問仍需互斥進行,所以需要
一個互斥信號量Rmutex。
3.思考問題
對于讀者---寫者問題,有以下三種策略。
1>讀者優先。即當讀者進行讀時,后續的寫者必須等待,直到所有的讀者均離開后,寫著才可進入。
2>寫者優先。即當一個寫者到來時,只有那些已經獲得授權允許讀的進程才允許完成他們的操作,
寫者之后到來的讀者將被推遲,直到寫者完成。在該策略中,如果有一個不可中斷的連續的寫者,
讀者進程會被無限期的推遲。
3>公平策略。以上兩種策略,讀者或寫進程中一個對一個有絕對的優先權,Hoare提出了一種更公平
的策略,由如下規則定義。
規則1:在一個讀序列中,如果有寫者在等待,那么就不允許有新的讀者開始執行。
規則2:在一個寫操作結束時,所有等待的讀者應該比下一個寫者有更高的優先權。
對于公平策略,又如何解決呢?
?
#include <pthread.h> #include <semaphore.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include<stdlib.h> int Rcount=0,num=0; //被保護的全局變量 sem_t Wmutex,Rmutex,mutex; void* read1(void *arg) {sem_wait(&mutex);sem_wait(&Rmutex);//讀者到來if(Rcount==0){printf("第一個讀者到來\n");sem_wait(&Wmutex);}Rcount=Rcount+1;//讀者數目sem_post(&Rmutex);sem_post(&mutex);printf("線程%lu正在進行讀數據%d\n",pthread_self(),num);sleep(1);sem_wait(&Rmutex);//讀者閱讀結束Rcount=Rcount-1;if(Rcount==0)//所有的讀者閱讀結束 {sem_post(&Wmutex);printf("讀者全部退出\n");}sem_post(&Rmutex); }void* write1(void *arg) {sem_wait(&mutex);sem_wait(&Wmutex);num=num+1;printf("線程%lu正在進行寫數據%d\n",pthread_self(),num);sem_post(&Wmutex);sem_post(&mutex); } int main(int argc,char *argv[]) { int i=0;int j=3;pthread_t tid[5];sem_init(&Wmutex,0,1); sem_init(&Rmutex,0,1); sem_init(&mutex,0,1); while(i<=2){if((pthread_create(&tid[i],NULL,read1,NULL))!=0){printf("can't create pthread.\n");exit(0);}i++;}while(j<=4){if((pthread_create(&tid[j],NULL,write1,NULL))!=0){printf("can't create pthread.\n");exit(0);}j++;}for(i=0;i<5;i++)pthread_join(tid[i],NULL); sem_destroy(&Wmutex); sem_destroy(&Rmutex); printf("程序運行結束\n");return 0; } 寫者優先?
#include <pthread.h> #include <semaphore.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include<stdlib.h> int Rcount=0,num=0; //被保護的全局變量 sem_t Wmutex,Rmutex; void* read1(void *arg) {sem_wait(&Rmutex);//讀者到來if(Rcount==0){printf("第一個讀者到來\n");sem_wait(&Wmutex);}Rcount=Rcount+1;//讀者數目sem_post(&Rmutex);printf("線程%lu正在進行讀數據%d\n",pthread_self(),num);sleep(1);sem_wait(&Rmutex);//讀者閱讀結束Rcount=Rcount-1;if(Rcount==0)//所有的讀者閱讀結束 {sem_post(&Wmutex);printf("讀者全部退出\n");}sem_post(&Rmutex);}void* write1(void *arg) {sem_wait(&Wmutex);num=num+1;printf("線程%lu正在進行寫數據%d\n",pthread_self(),num);sem_post(&Wmutex); } int main(int argc,char *argv[]) { int i=0;int j=3;pthread_t tid[5];sem_init(&Wmutex,0,1); // 空閑的sem_init(&Rmutex,0,1); // 忙的while(i<=2){if((pthread_create(&tid[i],NULL,read1,NULL))!=0){printf("can't create pthread.\n");exit(0);}i++;}while(j<=4){if((pthread_create(&tid[j],NULL,write1,NULL))!=0){printf("can't create pthread.\n");exit(0);}j++;}for(i=0;i<5;i++)pthread_join(tid[i],NULL); sem_destroy(&Wmutex); sem_destroy(&Rmutex); printf("程序運行結束\n");return 0; } 讀者優先?
轉載于:https://www.cnblogs.com/leijiangtao/p/4503121.html
總結
- 上一篇: PHP读取大文件的几种方法
- 下一篇: javascript实现jsonp跨域问