信号量 读者写者问题

写了两个小程序验证
1 /*
 2  *   读者写者问题,读者优先
 3  *   <<操作系统-内核与设计原理>> p183,p184
 4  *   有读者在读那么后来的读者就可以继续读,而已经在等待的写者继续等待,
 5  *   直到某个时刻没有任何读者。
 6  *   读者之间不互斥,写者之间互斥,只能一个写,可以多个读,
 7  *   读者写者之间互斥,有写者写则不能有读者读
 8  *   所以只需要当前第一个读者和写者竞争,竞争成功则后面的读者因为
 9  *   已经有读者在读,可以直接读。
10  */
11 #include  <stdio.h>
12 #include  <pthread.h>
13 #include  <ctype.h>
14 #include <semaphore.h>
15 
16 static sem_t sem_x;  //保证readcount被正确更新
17 static sem_t sem_wsem; //保证读写,写写互斥
18 static int readcount = 0;
19 void *write(void *a) 
20 {
21     sem_wait(&sem_wsem);
22     
23     //writting
24     printf("Writer is writting no reader allowed\n");
25     sleep(2);
26     printf("Finished writting\n");
27     //end of writting
28 
29     sem_post(&sem_wsem);
30 }
31 
32 void *read(void *a) 
33 {
34     int *= (int *)a;
35     int tid = *+ 1;
36     int i;
37     for (i = 0; i < 2; i++) {
38         sem_wait(&sem_x);
39         readcount++;
40         printf("Reader count is %d\n", readcount);
41         if (readcount == 1)
42             sem_wait(&sem_wsem);
43         sem_post(&sem_x);
44 
45         //reading
46         printf("Reader %d is reading\n", tid);
47         sleep(2);
48         printf("Finshed reading\n");
49 
50         sem_wait(&sem_x);
51         readcount--;
52         if (readcount == 0)
53             sem_post(&sem_wsem);
54         sem_post(&sem_x);
55     }
56 }
57 
58 int main(int argc, char *argv[])
59 {
60     pthread_t reader_tid[20];
61     pthread_t writer_tid[10];
62     
63     //init semaphore
64     if(sem_init(&sem_x,01== -1 ||
65        sem_init(&sem_wsem, 01== -1) {
66         printf("Failed to init semaphore!\n");
67         exit(1);
68     }
69 
70     int i;
71     for (i = 0; i < 10; i++)
72         pthread_create(&reader_tid[i], NULL, read,(void *&i);
73     for (i = 0; i < 5; i++)
74         pthread_create(&writer_tid[i], NULL, write, (void *&i);
75     for (i = 10; i < 20; i++)
76         pthread_create(&reader_tid[i], NULL, read,(void *&i);
77     for (i = 5; i < 10; i++)
78         pthread_create(&writer_tid[i], NULL, write,(void *&i);
79 
80     for (i = 0; i < 20; i++)
81         pthread_join(reader_tid[i], NULL);
82     for (i = 0; i < 10; i++)
83         pthread_join(writer_tid[i], NULL);
84 
85     printf("Final read count is %d\n", readcount);
86     return 0;
87 }
//test
Reader count is 1
Reader 1 is reading
Reader count is 2
Reader 2 is reading
Reader count is 3
Reader 3 is reading
Reader count is 4
Reader 4 is reading
Reader count is 5
Reader 5 is reading
Reader count is 6
Reader 6 is reading
Reader count is 7
Reader 7 is reading
Reader count is 8
Reader 8 is reading
Reader count is 9
Reader 9 is reading
Reader count is 10
Reader 10 is reading
Reader count is 11
Reader 11 is reading
Reader count is 12
Reader 12 is reading
Reader count is 13
Reader 13 is reading
Reader count is 14
Reader 14 is reading
Reader count is 15
Reader 15 is reading
Reader count is 16
Reader 16 is reading
Reader count is 17
Reader 17 is reading
Reader count is 18
Reader 18 is reading
Reader count is 19
Reader 19 is reading
Reader count is 20
Reader 20 is reading
Finshed reading
Reader count is 20
Reader 1 is reading
Finshed reading
Reader count is 20
Reader 2 is reading
Finshed reading
Reader count is 20
Reader 3 is reading
Finshed reading
Reader count is 20
Reader 4 is reading
Finshed reading
Reader count is 20
Reader 5 is reading
Finshed reading
Reader count is 20
Reader 6 is reading
Finshed reading
Reader count is 20
Reader 7 is reading
Finshed reading
Reader count is 20
Reader 8 is reading
Finshed reading
Reader count is 20
Reader 9 is reading
Finshed reading
Reader count is 20
Reader 10 is reading
Finshed reading
Reader count is 20
Reader 11 is reading
Finshed reading
Reader count is 20
Reader 12 is reading
Finshed reading
Reader count is 20
Reader 13 is reading
Finshed reading
Reader count is 20
Reader 14 is reading
Finshed reading
Reader count is 20
Reader 15 is reading
Finshed reading
Reader count is 20
Reader 16 is reading
Finshed reading
Reader count is 20
Reader 17 is reading
Finshed reading
Reader count is 20
Reader 18 is reading
Finshed reading
Reader count is 20
Reader 19 is reading
Finshed reading
Reader count is 20
Reader 20 is reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Writer is writting no reader allowed
Finished writting
Final read count is 0



  1 /*
  2  *   读者写者问题,写者优先
  3  *   <<操作系统-内核与设计原理>> p185,p16
  4  *  当写者出现后,后来的读者会被阻塞,直到没有写者。
  5  *  
  6  *  第一个读者和写者竞争,如果失败了,证明有写者
  7  *  后来的读者将在另一个信号量上排队。
  8  *  
  9  *  在rsem不允许建立读者长队列,否则当同时有很多读进程
 10  *  和第一个写者出现,可能写者会在rsem的竞争中排在后面
 11  *  不能跳过前面的读者。保证了第一写者writecount=1的优先地位,
 12  *  但是实验一般测不出来,有没有sem_z一样的,因为,读者在rsem
 13  *  上排队的时间太短了,比如writecount == 0了 singnal rsem
 14  *  然后很快的所有排队的读者就都获得了读的权利,队列变空。除非实验能够
 15  *  在这个时候出先一个写者,这样有sem_z则写者至多让前面的一个读者读,
 16  *  就取得了写权利,
 17  *  而没有的话,rsem对了写者前面的都会去读,意义不大。
 18  *  if (writecount == 1)    
 19         sem_wait(&sem_rsem);
 20     确保了后续写者相对读者的优先地位.这个是主要的写者优势。
 21  */
 22 #include  <stdio.h>
 23 #include  <pthread.h>
 24 #include  <ctype.h>
 25 #include <semaphore.h>
 26 
 27 static sem_t sem_x;     //保证readcount被正确更新
 28 static sem_t sem_y;     //保证writercount被正确更新
 29 static sem_t sem_z;     //竞争rsem失败后,后续读者在此排队
 30 static sem_t sem_wsem;  //保证读写,写写互斥
 31 static sem_t sem_rsem;  //当一个写者出现,用于禁止所有的读进程
 32 static int readcount = 0;
 33 static int writecount = 0;
 34 void *write(void *a) 
 35 {
 36     int *= (int *)a;
 37     int tid = *+ 1;
 38     sem_wait(&sem_y);
 39     writecount++;
 40     printf("Writter count is %d\n", writecount);
 41     if (writecount == 1)    //写者在rsem的竞争中优先
 42         sem_wait(&sem_rsem);
 43     sem_post(&sem_y);
 44     
 45     sem_wait(&sem_wsem);
 46 
 47     //writting
 48     printf("Writer %d is writting no reader allowed\n", tid);
 49     sleep(2);
 50     printf("Finished writting\n");
 51     //end of writting
 52 
 53     sem_post(&sem_wsem);
 54 
 55     sem_wait(&sem_y);
 56     writecount--;
 57     if (writecount == 0)
 58         sem_post(&sem_rsem);
 59     sem_post(&sem_y);
 60 }
 61 
 62 void *read(void *a) 
 63 {
 64     int *= (int *)a;
 65     int tid = *+ 1;
 66     int i;
 67     for (i = 0; i < 2; i++) {
 68         sem_wait(&sem_z);
 69         sem_wait(&sem_rsem);
 70         sem_wait(&sem_x);
 71         readcount++;
 72         printf("Reader count is %d\n", readcount);
 73         if (readcount == 1)
 74             sem_wait(&sem_wsem);
 75         sem_post(&sem_x);
 76         sem_post(&sem_rsem);
 77         sem_post(&sem_z);
 78 
 79         //reading
 80         printf("Reader %d is reading\n", tid);
 81         sleep(2);
 82         printf("Finshed reading\n");
 83         //end of reading
 84 
 85         sem_wait(&sem_x);
 86         readcount--;
 87         if (readcount == 0)
 88             sem_post(&sem_wsem);
 89         sem_post(&sem_x);
 90     }
 91 }
 92 
 93 int main(int argc, char *argv[])
 94 {
 95     pthread_t reader_tid[20];
 96     pthread_t writer_tid[10];
 97     
 98     //init semaphore
 99     if(sem_init(&sem_x,01== -1 ||
100        sem_init(&sem_y,01== -1 ||
101        sem_init(&sem_z,01== -1 ||
102        sem_init(&sem_wsem, 01== -1 ||
103        sem_init(&sem_rsem, 01== -1) {
104         printf("Failed to init semaphore!\n");
105         exit(1);
106     }
107 
108     int i;
109     for (i = 0; i < 10; i++)
110         pthread_create(&reader_tid[i], NULL, read,(void *&i);
111     for (i = 0; i < 5; i++)
112         pthread_create(&writer_tid[i], NULL, write, (void *&i);
113     for (i = 10; i < 20; i++)
114         pthread_create(&reader_tid[i], NULL, read,(void *&i);
115     for (i = 5; i < 10; i++)
116         pthread_create(&writer_tid[i], NULL, write,(void *&i);
117 
118     for (i = 0; i < 20; i++)
119         pthread_join(reader_tid[i], NULL);
120     for (i = 0; i < 10; i++)
121         pthread_join(writer_tid[i], NULL);
122 
123     return 0;
124 }
//test
Reader count is 1
Reader 1 is reading
Reader count is 2
Reader 2 is reading
Reader count is 3
Reader 3 is reading
Reader count is 4
Reader 4 is reading
Reader count is 5
Reader 5 is reading
Reader count is 6
Reader 6 is reading
Reader count is 7
Reader 7 is reading
Reader count is 8
Reader 8 is reading
Reader count is 9
Reader 9 is reading
Reader count is 10
Reader 10 is reading
Writter count is 1
Writter count is 2
Writter count is 3
Writter count is 4
Writter count is 5
Writter count is 6
Writter count is 7
Writter count is 8
Writter count is 9
Writter count is 10
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Writer 1 is writting no reader allowed
Finished writting
Writer 2 is writting no reader allowed
Finished writting
Writer 3 is writting no reader allowed
Finished writting
Writer 4 is writting no reader allowed
Finished writting
Writer 5 is writting no reader allowed
Finished writting
Writer 6 is writting no reader allowed
Finished writting
Writer 7 is writting no reader allowed
Finished writting
Writer 8 is writting no reader allowed
Finished writting
Writer 9 is writting no reader allowed
Finished writting
Writer 10 is writting no reader allowed
Finished writting
Reader count is 1
Reader 11 is reading
Reader count is 2
Reader 12 is reading
Reader count is 3
Reader 13 is reading
Reader count is 4
Reader 14 is reading
Reader count is 5
Reader 15 is reading
Reader count is 6
Reader 16 is reading
Reader count is 7
Reader 17 is reading
Reader count is 8
Reader 18 is reading
Reader count is 9
Reader 19 is reading
Reader count is 10
Reader 20 is reading
Reader count is 11
Reader 1 is reading
Reader count is 12
Reader 2 is reading
Reader count is 13
Reader 3 is reading
Reader count is 14
Reader 4 is reading
Reader count is 15
Reader 5 is reading
Reader count is 16
Reader 6 is reading
Reader count is 17
Reader 7 is reading
Reader count is 18
Reader 8 is reading
Reader count is 19
Reader 9 is reading
Reader count is 20
Reader 10 is reading
Finshed reading
Reader count is 20
Reader 11 is reading
Finshed reading
Reader count is 20
Reader 12 is reading
Finshed reading
Reader count is 20
Reader 13 is reading
Finshed reading
Reader count is 20
Reader 14 is reading
Finshed reading
Reader count is 20
Reader 15 is reading
Finshed reading
Reader count is 20
Reader 16 is reading
Finshed reading
Reader count is 20
Reader 17 is reading
Finshed reading
Reader count is 20
Reader 18 is reading
Finshed reading
Reader count is 20
Reader 19 is reading
Finshed reading
Reader count is 20
Reader 20 is reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
Finshed reading
 
原文地址:https://www.cnblogs.com/rocketfan/p/1533194.html