经典的进程同步问题
1、信号量
信号量机制是一种功能较强大的机制,可用来解决互斥和同步问题,它只能被两个标准的原语 wait(S) 和 signal(S) 访问,也可记为 “P 操作” 和 ”V 操作“。
1.1、整型信号量
整型信号量被定义为一个用来表示资源数目的整型量 S,wait 和 signal 操作可描述为:
wait(S){
while(S<=0);
S = S-1;
}
signal(S){
S = S+1;
}
1.2、记录型信号量
typedef struct{
int value;
struct process *L;
}semaphore;
wait 和 signal 操作可描述为:
void wait(semaphore S){
//相当于申请资源
S.value--;
if(S.value < 0){
插入等待队列;
block(S.L);
}
}
void signal(semaphore S){
//相当于释放资源
S.value++;
if(S.value <= 0){
从队列中唤醒一个进程;
wakeup(P);
}
}
2、经典的同步问题
2.1、生产者-消费者问题
2.1.1、生产者-消费者问题
2.1.2、多生产者-多消费者问题
问题描述:
桌子上有一个盘子,每次只能向其中放入一个水果。爸爸专门向盘子中放苹果,妈妈专门向盘子中放橘子,儿子专门等吃盘子中的橘子,女儿专门等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈才能向盘子中放一个水果;仅当盘子中有自己吃的水果时,女儿或儿子可以从盘子中取出。
伪代码:
semaphore plate = 1,apple = 0,orange = 0;
dad(){
//父亲进程
while(1){
prepare an apple;
P(plate); //互斥向盘中取、放水果
put the apple on the plate;
V(apple); //允许取苹果
}
}
mom(){
//母亲进程
while(1){
prepare an orange;
P(plate); //互斥向盘中取、放水果
put the orange on the plate;
V(porange); //允许取橘子
}
}
daughter(){
//女儿进程
while(1){
P(apple); //互斥从盘中取苹果
take an apple from the plate;
V(plate); //允许向盘中放水果
eat the apple
}
}
son(){
//儿子进程
while(1){
P(orange); //互斥从盘中取橘子
take an orange from the plate;
V(plate); //允许向盘中放水果
eat the orange;
}
}
Python 语言实现:
from threading import Thread,Semaphore
from queue import Queue
from random import randint
from time import sleep
class MyThread(Thread): #创建进程类
def __init__(self,func,args,name=''):
Thread.__init__(self)
self.name = name
self.func = func
self.args = args
def run(self):
self.func(*self.args)
plate = Semaphore(1) #盘子信号量
orange = Semaphore(0) #橘子信号量
apple = Semaphore(0) #苹果信号量
q = Queue(1) #共享存储
def dad(queue):
while(True):
plate.acquire() #互斥向盘子中放水果
queue.put('apple')