死锁

死锁产生的原因有两个:
1.多进程或多线程对不可剥夺的软硬件资源进行的竞争
2.操作系统内核对于多个进程推进顺序的非法,多个进程对于资源的请求与释放的顺序不正确,造成资源的死锁。

程序员对信号量的使用不当,造成应用程序内部多进程或多线程的死锁。
程序员对互斥锁的使用不当,也会造成死锁,自己锁自己,这里的死锁并不是操作系统意义上的死锁,而是编程层面未对互斥锁成对(lock unlock)使用造成的。

#include <thread>
#include <semaphore.h>
#include <iostream>
#include <unistd.h>
using namespace std;

sem_t s1, s2; // 两个用于同步的信号量
int main() {
	sem_init(&s1, 0, 0);
	sem_init(&s2, 0, 0);
	thread t1([&](){
		sem_wait(&s2);  // 请求持有s2 陷入阻塞
		cout << "hello" << endl;
		sem_post(&s1);  // 持有s1 但不能释放
	});
	
	thread t2([&](){
		sem_wait(&s1); // 请求持有s1  陷入阻塞
		cout << "hello" << endl;
		sem_post(&s2); // 持有s2 但不能释放
	});
	
	sem_destroy(&s1);
	sem_destroy(&s2);
	return 0;
}

在这里插入图片描述

上述两个两个线程分别持有一个信号量,但是又请求占用对方的信号量。
满足互斥条件,满足不可剥夺条件,满足请求保持条件,满足循环等待条件,最终造成两个线程死锁,在无外力条件的破坏的情况下,两线程将永远不会向前推进。

#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mtx;
int x=10;

int main() {
	pthread_mutex_init(&mtx, NULL);
	pthread_mutex_lock(&mtx);// 对mutex加锁成功 
	pthread_mutex_lock(&mtx);
	// 还未对mutex解锁 将会永久阻塞
	x += 100;
	pthread_mutex_unlock(&mtx);
	pthread_mutex_destroy(&mtx);
	return 0;
}

死锁预防
死锁预防的本质就是釜底抽薪,直接从根本上干掉死锁,避免死锁的发生。破坏死锁的四个必要条件的一个或多个。
互斥条件:几乎不可行

不可剥夺条件:强行剥夺,是要付出代价的。强行剥夺可能会造成进程或线程前一段工作的失效,只适用在一些易于保存和恢复的资源。

请求和保持条件:代价太高,一次性分配完,系统没有那么多资源,造成资源的浪费。

循环等待条件:顺序资源分配
资源递增编号 进程或线程按序申请使用资源

死锁避免
银行家算法

死锁检测与解除
死锁定理+资源分配图

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值