- 计算1812
- 江雄鹏
- 201821121043
一、实验目的
通过编程进一步了解信号量。
二、实验内容
在服务器上用Vim编写一个程序:使用信号量解决任一个经典PV问题,测试给出结果,并对解释运行结果。
- 生产者-消费者问题
- 读者-写者问题
- 哲学家进餐问题
三、实验报告
1. 选择哪一个问题
选择读者-写者问题
(1)情况:对象在多个线程之间共享,一些线程只读数据,一些线程只写数据。为保证写入和读取的正确性,操作限制:
- 写-写互斥和读-写互斥,即不能有两个写者同时进行写操作和不能同时有一个线程在读,而另一个线程在写。
- 读-读允许,即可以有一个或多个读者在读。
(2)解决方案:读者优先或写者优先。
2. 给出伪代码
(1)读者优先
void* writer(void* arg) 17 { 18 int i = *(int*)arg; 19 printf("the process%dwant to write\n",i); 20 sem_wait(&mutex2); 21 writecount++; 22 if(writecount==1) //若第一个为写者,阻止后续的读者 23 sem_wait(&r); 24 sem_post(&mutex2); 25 sem_wait(&w);//写者互斥 26 printf("the process%dis writing\n",i); 27 sleep(4); 28 printf("the process%dhas written\n",i); 29 sem_post(&w); 30 sem_wait(&mutex2); 31 writecount--; 32 if(writecount==0) sem_post(&r);//所有的写者写完才能让P(r)的读者readcount增加 33 sem_post(&mutex2); 34 } 35
(2)写者优先
void* reader(void* arg){ 37 int i = *(int*)arg; 38 printf("the process%dwant to read\n",i); 39 sem_wait(&mutex3); 40 sem_wait(&r); 41 sem_wait(&mutex1); 42 readcount++; 43 if(readcount==1)//若第一个为读者,互斥写者 44 sem_wait(&w); 45 sem_post(&mutex1); 46 sem_post(&r); 47 sem_post(&mutex3); 48 printf("the process%dis reading\n",i); 49 sleep(2); 50 printf("the process%dhas read\n",i); 51 sem_wait(&mutex1); 52 readcount--; 53 if(readcount==0)//读者运行完释放写者,读写互斥 54 sem_post(&w); 55 sem_post(&mutex1); 56 57 }
3. 完整代码
4. 运行结果并解释
解释:0~7一共8个进程,进程1等待进程0完成写入后进行读取;当进程2想要读取时,此时进程1还在读取,所以进程2能够实现与进程1同时读取;进程3想要写入,得等进程1和2读取完毕才能开始写入;当进程4、5、6想要读取时,只有当进程3完成写入才能读取;当进程7想要写入时,因为写入与读写的操作不能同时进行,所以只有等待进程4,5,6读取完毕后,进程7才能写入。