信号量 同步 死锁

#include "wrapper.h"   /*多线程输出10行ABC*/
sem_t go,a,b,c; /*a,b,c是用于同步的信号量*/
void* A(){
	sem_wait(&go);
	sem_wait(&c);
	printf("A");
	sem_post(&go);
	sem_post(&a);
	return NULL;
}
void* B(){
	sem_wait(&go);
	sem_wait(&a);
	printf("B");
	sem_post(&go);
	sem_post(&b);
	return NULL;
}
void* C(){
	sem_wait(&go);
	sem_wait(&b);
	printf("C");
	sem_post(&go);
	sem_post(&c);
	return NULL;
}
main(){
	sem_init(&a,0,1); 
	sem_wait(&a);
	sem_init(&b,0,1); 
	sem_wait(&b);
	sem_init(&c,0,1); 
	sem_init(&go,0,1); 
	pthread_t t1,t2,t3;
	int i;
	for(i=0;i=10;i++){
	pthread_create(&t1,NULL,A,NULL);
	pthread_create(&t2,NULL,B,NULL);
	pthread_create(&t3,NULL,C,NULL);
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);
	pthread_join(t3, NULL);
	printf("\n");
	}
	
	sem_destroy(&go);
	sem_destroy(&a);
	sem_destroy(&b);
	sem_destroy(&c);
	exit(0);
}

以上程序运行会出现死锁现象

运行后挂在那没反应

原因在 go 信号量

本来我设置这个信号量是想控制各线程同一时间只能有一个输出

但是,这也导致了死锁

来看这一段

void* A(){
	sem_wait(&go);
	sem_wait(&c);
	printf("A");
	sem_post(&go);
	sem_post(&a);
	return NULL;
}
void* B(){
	sem_wait(&go);
	sem_wait(&a);
	printf("B");
	sem_post(&go);
	sem_post(&b);
	return NULL;
}

看函数B()

假设B先获得信号量go

则其他线程阻塞在sem_wait(&go)

但是B也会阻塞在sem_wait(&a)

因为B先于A获得信号量go

A还没能执行sem_post(&go) 释放信号

然后全部线程都被阻塞了,没有线程能跳出来拯救

死锁了

解决办法:
把信号量go删了

#include "wrapper.h"
sem_t go,a,b,c;
void* A(){
	sem_wait(&c);
	printf("A");
	sem_post(&a);
	return NULL;
}
void* B(){
	sem_wait(&a);
	printf("B");
	sem_post(&b);
	return NULL;
}
void* C(){
	sem_wait(&b);
	printf("C");
	sem_post(&c);
	return NULL;
}
main(){
	sem_init(&a,0,1); 
	sem_wait(&a);
	sem_init(&b,0,1); 
	sem_wait(&b);
	sem_init(&c,0,1); 
	sem_init(&go,0,1); 
	pthread_t t1,t2,t3;
	int i;
	for(i=0;i<10;i++){
	pthread_create(&t1,NULL,A,NULL);
	pthread_create(&t2,NULL,B,NULL);
	pthread_create(&t3,NULL,C,NULL);
	pthread_join(t1, NULL);
	pthread_join(t2, NULL);
	pthread_join(t3, NULL);
	printf("\n");
	}
	sem_destroy(&a);
	sem_destroy(&b);
	sem_destroy(&c);
	exit(0);
}

运行结果就是10行ABC

其实是我想多了,有信号量a,b,c保证同步就已经足够了

信号量go完全是多余的

另外,这个程序也告诉了我多线程编程的时候别被 “临界区” 这个概念给局限了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值