<aside> ❓
能否改变相邻 P、V 操作的顺序?
P 操作的顺序不能交换,否则发生死锁;V 操作的顺序可以交换
实现互斥的P操作一定要在实现同步的P操作之后,否则可能引起“死锁”
</aside>
<aside> 💡
使用产品操作不要放在临界区中,加锁的粒度尽量小
</aside>
桌子上有一只盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等着吃盘子中的橘子,女儿专等着吃盘子中的苹果。只有盘子空时,爸爸或妈妈才可向盘子中放一个水果。仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出水果。
找出同步、互斥关系
互斥关系: 对缓冲区(盘子)的访问要互斥地进行 同步关系(一前一后): 1.父亲将苹果放入盘子后,女儿才能取苹果 2.母亲将橘子放入盘子后,儿子才能取橘子 3.只有盘子为空时,父亲或母亲才能放入水果
尝试优化:无需互斥信号量 mutex 也可以
<aside> ❓
如果如果盘子容量为 2,还能取消掉 mutex 信号量吗?
不能,可能会出现两个生产者同时写入,覆盖对方的数据的情况
结论:如果缓冲区大小大于 1,就必须专门设置一个互斥信号量 mutex 来保证树池访问缓冲区
</aside>
假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它,但是要卷起并抽掉一支烟,抽烟者需要有三种材料:烟草、纸和胶水。三个抽烟者中,第一个拥有烟草、第二个拥有纸、第三个拥有胶水。供应者进程无限地提供三种材料,供应者每次将两种材料放桌子上,拥有剩下那种材料的抽烟者卷一根烟并抽掉它,并给供应者进程一个信号告诉完成了,供应者就会放另外两种材料再桌上,这个过程一直重复(让三个抽烟者轮流地抽烟)
<aside> ❓
如何实现轮流的需求?
通过代码中专门的变量 i 来实现
</aside>
有读者和写者两组并发进程,共享一个文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:①允许多个读者可以同时对文件执行读操作;②只允许一个写者往文件中写信息;③任一写者在完成写操作之前不允许其他读者或写者工作;④写者执行写操作前,应让己有的读者和写者全部退出
如何实现读写公平算法?
semaphore rw = 1; // 用于实现对共享文件的互斥访问
int count = 0; // 记录当前有几个读进程在访问文件
semaphore mutex = 1; // 用于保证对 count 变量的互斥访问
semaphore w = 1; // 用于实现“写优先”
writer() {
while (1) {
P(w);
P(rw);
// 写文件...
V(rw);
V(w);
}
}
reader() {
while (1) {
P(w);
P(mutex);
if (count == 0)
P(rw);
count++;
V(mutex);
V(w);
// 读文件...
P(mutex);
count--;
if (count == 0)
V(rw);
V(mutex);
}
}
分析以下并发执行 P(w) 的情况: