死锁产生的原因有两个: 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;
}
死锁预防 死锁预防的本质就是釜底抽薪,直接从根本上干掉死锁,避免死锁的发生。破坏死锁的四个必要条件的一个或多个。 互斥条件:几乎不可行
不可剥夺条件:强行剥夺,是要付出代价的。强行剥夺可能会造成进程或线程前一段工作的失效,只适用在一些易于保存和恢复的资源。
请求和保持条件:代价太高,一次性分配完,系统没有那么多资源,造成资源的浪费。
循环等待条件:顺序资源分配 资源递增编号 进程或线程按序申请使用资源
死锁避免 银行家算法
死锁检测与解除 死锁定理+资源分配图
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有