1. 用信号量解题步骤:(1)设置信号量(2)给信号量赋初值(3)P、V操作安排位置
2. 信号量实现进程互斥
![在这里插入图片描述](https://img-blog.csdnimg.cn/d23c4d0c13bb4393b695210a36130b9f.png)
2.1 互斥信号量取值范围 例:两个进程,取值范围(-1,0,1) m个进程,取值范围(1-m,1)
3. 信号量实现前趋关系
![在这里插入图片描述](https://img-blog.csdnimg.cn/e8515e2569dc4b1599e52d1c45c7165e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmVycnlfX0dvbmc=,size_15,color_FFFFFF,t_70,g_se,x_16)
例如: 解答: a = V(S1); V(S2) b = P(S1) c = P(S2) ;P(S3) d = p(S4)
4. 初始状态下:empter = 1,因为缓冲区“空”的位置有,所以为1;full = 0,因为缓冲器“满”的位置没有,所以为0.
5. 生产者–消费者问题
分析问题里有几个进程;分析之间存在互斥模式还是同步模式,例:生产者–消费者问题是互斥模式和同步模式; (1)一个生产者,一个消费者,共用一个缓冲区 代码: void producer( ) { while(true) { 生产一个产品; P(empty); 产品送往Buffer; V(full); } } void consumer( ) { while(true) { P(full); 从Buffer取出一个产品; V(empty); 消费该产品; } } (2)一个生产者,一个消费者,公用n个环形缓冲区 代码: void producer() { while(true) { 生产一个产品; P(empty);//申请一个空缓冲区 buffer[in] =nextp; in=(in+1)% n; V(full); //释放一个满缓冲区 } } void consumer() { while(true) { P(full); //申请一个满缓冲区 nextc = buffer[out]; out = (out+1)%n; V(empty); //释放一个空缓冲区 消费该产品; } } (3) 一组生产者,一组消费者,公用n个环形缓冲区 为什么存在互斥问题: 在这个问题中,不仅生产者与消费者之间要同步,而且各个生产者之间、各个消费者之间还必须互斥地访问缓冲区。 代码: void producer() { while(true) { 生产一个产品; P(empty); //申请一个空缓冲区 P(mutex1); //申请空缓冲区使用权 buffer[in] =nextp; in=(in+1)% n; V(mutex1); //释放空缓冲区使用权 V(full); //释放一个满缓冲区 } } void consumer() { while(true) { P(full); P(mutex2); nextc = buffer[out]; out = (out+1)%n; V(mutex2); V(empty); 消费该产品; } }
6. 哲学家进餐
定义互斥信号量组,筷子是临界资源,初始值为1 代码: semaphore chopstick[5] = {1,1,1,1,1}; do{ wait(chopstick[i]); //先取左手的筷子 左手的筷子都能拿起,但都不释放 wait(chopstick[(i+1)%5]); //再取右手的筷子 … //eat … signal(chopstick[i]); signal(chopstick[(i+1)%5]); … //think … }while(TRUE); (1) semaphore chopstick[5] = {1,1,1,1,1}; semaphore count=4; do{ wait(count); wait(chopstick[i]); wait(chopstick[(i+1)%5]); eat(); signal(chopstick[i]); signal(chopstick[(i+1)%5]); signal(count); think(); }while(TRUE); 3号先吃,然后2号,1号,0号,4号 (2) semaphore chopstick[5] = {1,1,1,1,1}; do{ Swait(chopstick[i], chopstick[(i+1)%5]); eat(); Ssignal(chopstick[i], chopstick[(i+1)%5]); think(); }while(TRUE); 0号,2号,1号,3号,4号 (3) semaphore chopstick[5] = {1,1,1,1,1}; do{ if(i%2==1) { P(chopstick[i]); P(chopstick[(i+1)%5]); eat(); V(chopstick[i]); V(chopstick[(i+1)%5]); think(); } else{ P(chopstick[(i+1)%5]); P(chopstick[i]); eat(); V(chopstick[i]); V(chopstick[(i+1)%5]); think(); } }while(TRUE); 0号,2号,1号,3号,4号
7. 读者–写者问题
类型:读、读共享,读、写互斥,写、写互斥。 互斥信号量,Readcount:表示正在读的进程数目 读操作的时候顺便把写操作也占用 ![在这里插入图片描述](https://img-blog.csdnimg.cn/762f276883a14ce39af5df2b93ce322c.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBASmVycnlfX0dvbmc=,size_20,color_FFFFFF,t_70,g_se,x_16)
8. 总结:P、V操作中何时该做的操作
一般情况下,empty=1,full=0。当进行wait操作时,就是要申请一个位置,因为empty=1,所以写empty,这样的话empty=1-1=0;然后进行signal操作的时候,就是释放一个位置,所以full=0+1=1。 也就是说,wait里填写的是不为0的值,signal里填写的是值为0的。
|