死锁问题总结

死锁

1、死锁产生的条件

死锁只有同时满足一下四个条件才会发生:
(1)互斥条件
互斥条件是指,多个线程不能同时使用同一个资源。
(2)持有并等待条件
持有并等待条件是指,当线程A已经持有了资源1,又想申请资源2,而资源2已经被线程B持有了,所以线程就会处于等待状态,但是线程A在等待资源2的同时并不会释放自己已经持有的资源1。
(3)不可剥夺条件
不可剥夺条件是指,当线程已经持有了资源,在自己使用完之前不能被其他线程获取。
(4)循环等待条件
循环等待条件是指,在死锁发生的时候,多个线程获取资源的顺序构成了环形链。

2、模拟死锁问题的产生

首先,我们先创建两个线程,分别为线程A和线程B,然后有两个互斥锁,分别是 mutex_A 和 mutex_B,代码如下:

pthread_mutex_t mutex_A = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_B = PTHREAD_MUTEX_INITIALIZER;

int main()
{
	pthread_t tidA, tidB;

	//创建两个线程
	pthread_create( &tidA, NULL, threadA_proc, NULL );
	pthread_create( &tidB, NULL, threadB_proc, NULL );
	
	pthread_join(tidA, NULL);
	pthread_join(tidB, NULL);
	
	printf("exit\n");
	return 0;
}

//线程函数 A
void *threadA_proc(void *data)
{
	printf("thread A waiting get ResourceA \n");
	pthread_mutex_lock( &mutex_A );
	printf("thread A got ResourceA \n");
	 
	sleep(1);
	
	printf("thread A waiting get ResourceB \n");
	pthread_mutex_lock(&mutex_B);
	printf("thread A got ResourceB \n");

	pthread_mutex_unlock(&mutex_B);
	pthread_mutex_unlock(&mutex_A);
	return (void *) 0;
}

//线程函数B
void *threadB_proc(void *data)
{
	printf("thread B waiting get ResourceB \n");
	pthread_mutex_lock( &mutex_B );
	printf("thread B got ResourceB \n");
	 
	sleep(1);
	
	printf("thread B waiting get ResourceA \n");
	pthread_mutex_lock(&mutex_A);
	printf("thread B got ResourceA \n");

	pthread_mutex_unlock(&mutex_A);
	pthread_mutex_unlock(&mutex_B);
	return (void *) 0;
}

3、避免死锁问题的发生

前面提到产生死锁的四个必要条件是:互斥条件、持有并等待条件、不可剥夺条件和循环等待条件。

那么避免死锁问题就只需要破坏其中一个条件就可以,最常见的并且可执行的就是使用资源有序分配法,来破坏循环等待条件。

什么是资源有序分配法呢?

线程A和线程B获取资源的顺序要一样,当线程A是先尝试获取资源A,然后尝试获取资源B的时候,线程B同样也是先尝试获取资源A。然后尝试获取资源B,也就是说,线程A和线程B总是以相同的顺序申请自己想要的资源。

我们使用资源有序分配法的方式来修改前面发生死锁的代码,我们可以不改动线程A的代码,只改动线程B的代码。

线程B函数改进后的代码如下:

//线程 B 的函数,同线程A一样,先获取互斥锁A,再获取互斥锁B
void *threadB_proc(void *data)
{
	printf("thread B waiting get ResourceA \n");
	pthread_mutex_lock( &mutex_A );
	printf("thread B got ResourceA \n");
	 
	sleep(1);
	
	printf("thread B waiting get ResourceB \n");
	pthread_mutex_lock(&mutex_B);
	printf("thread B got ResourceB \n");

	pthread_mutex_unlock(&mutex_B);
	pthread_mutex_unlock(&mutex_A);
	return (void *) 0;
}

总结

简单来说,死锁问题的产生是由两个或者以上线程并行执行的时候,争夺资源而相互等待造成的。

死锁只有同时满足互斥、持有并等待、不可剥夺和环路等待四个条件的时候才会发生。

所以要避免死锁问题,就是要破坏其中一个条件即可,最常用的方法就是使用资源有序分配法来破坏环路等待条件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值