生产者消费者问题

进程间关系为“生产资源-消费资源”

semaphore mutex = 1;
semaphore full = 0;
semaphore empty = n;
 
producer(){
	while(1){
		produce an item;//生产数据
		P(empty);
		P(mutex);
		add to buffer;//将数据放入缓冲区
		V(mutex);
		V(full);
	}
}
 
consumer(){
	while(1){
		P(full);
		P(mutex);
		remove an item from buffer;//从缓冲区取出数据
		V(mutex);
		V(empty);
		consume the item;//消费数据
	}
}

理发师问题

进程间关系为“服务-被服务”

最基础的模板:无等待上限,服务人员可休息

semaphore server = 0;
semaphore customer = 0;
semaphore mutex = 1;
 
server(){
	while(1){
		P(customer);
		P(mutex);
		叫号;
		V(mutex);
		V(server);
		提供服务;
	}
}
 
customer(){
	while(1){
		P(mutex);
		取号;
		V(mutex);
		V(customer);
		P(server);
		被服务;
	}
}

读者写者问题

同类进程不互斥、异类进程互斥

int count = 0;
semophore mutex = 1;//更新count时互斥
semophore rw = 1;//读进程和写进程互斥
semophore w = 1;//优先写进程
 
writer(){
	while(1){
		P(w);
		P(rw);
		writing;
		V(rw);
		V(w);
	}
}
 
reader(){
	while(1){
		P(w);
		P(mutex);
		if(count == 0) P(rw);//第一个读进程加锁
		count++;
		V(mutex);
		V(w);
		reading;
		P(mutex);
		count--;
		if(count == 0)V(rw);//最后一个读进程解锁
		V(mutex);
	}
}

哲学家进餐问题

只有一类进程,每个进程需要同时拥有多种资源才能运行

semaphore chopsticks[5] = {1,1,1,1,1};//下标为i的筷子代表第i位哲学家右手边的筷子
 
//方法一:当一个哲学家左右筷子都可用时,一起拿起左右两只筷子
semaphore mutex = 1;
pi(int i){
	while(1){
		P(mutex);
		P(chopsticks[i]);
		P(chopsticks[((i-1)+5)%5]);//左手的筷子
		V(mutex);
		eat;
		V(chopsticks[i]);
		V(chopsticks[((i-1)+5)%5]);
		think;
	}
}
 
//方法二:至多允许四个哲学家同时用餐
semaphore num = 4;
pi(int i){
	while(1){
		P(num);
		P(chopsticks[i]);
		P(chopsticks[((i-1)+5)%5]);
		eat;
		V(chopsticks[i]);
		V(chopsticks[((i-1)+5)%5]);
		V(num);
		think;
	}
}
 
//方法三:对哲学家编号,奇数号的先拿左边筷子,偶数号的正好相反
pi(int i){
	while(1){
		if(i%2==1){
			P(chopsticks[((i-1)+5)%5]);
			P(chopsticks[i]);
			eat;
			V(chopsticks[((i-1)+5)%5]);
			V(chopsticks[i]);
			think;
		}else{
			P(chopsticks[i]);		
			P(chopsticks[((i-1)+5)%5]);
			eat;
			V(chopsticks[i]);
			V(chopsticks[((i-1)+5)%5]);
			think;
		}
	}
}

单纯的同步问题

前驱后继图

semaphore s12=s13=s24=s25=s46=s56=s36
 
S1(){
	...;
	V(s12);
	V(s13);
}
 
S2(){
	P(s12);
	...;
	V(s24);
	V(s25);
}
 
S3(){
	P(s13);
	...;
	V(s36);
}
 
S4(){
	P(s24);
	...;
	V(s46);
}
 
S5(){
	P(s25);
	...;
	V(s56);
}
 
S6(){
	P(s46);
	P(s56);
	P(s36);
	...;
}