D死锁和R死锁

作者:【吴业亮】

博客:https://wuyeliang.blog.csdn.net/

死锁
  死锁是指多个进程(线程)因为长久等待已被其他进程占有的的资源而陷入阻塞的一种状态。当等待的资源一直得不到释放,死锁会一直持续下去。死锁一旦发生,程序本身是解决不了的,只能依靠外部力量使得程序恢复运行,例如重启,开门狗复位等。

Linux 提供了检测死锁的机制,主要分为 D 状态死锁和 R 状态死锁。

D 状态死锁
进程等待 I/O 资源无法得到满足,长时间(系统默认配置 120 秒)处于 TASK_UNINTERRUPTIBLE 睡眠状态,这种状态下进程不响应异步信号(包括 kill -9)。如:进程与外设硬件的交互(如 read),通常使用这种状态来保证进程与设备的交互过程不被打断,否则设备可能处于不可控的状态。对于这种死锁的检测 Linux 提供的是 hung task 机制。触发该问题成因比较复杂多样,可能因为 synchronized_irq、mutex lock、内存不足等。D 状态死锁只是局部多进程间互锁,一般来说只是 hang 机、冻屏,机器某些功能没法使用,但不会导致没喂狗而系统死机。
在这里插入图片描述

R 状态死锁
进程长时间(系统默认配置 60 秒)处于 TASK_RUNNING 状态垄断 CPU 而不发生切换,一般情况下是进程关抢占或关中断后长时候执行任务、死循环,此时往往会导致多 CPU 间互锁,整个系统无法正常调度,导致喂狗线程无法执行,无法喂狗而最终看门狗复位的重启。该问题多为原子操作,spinlock 等 CPU 间并发操作处理不当造成。
在这里插入图片描述
参考:
https://blog.csdn.net/luckyapple1028/article/details/51931210
https://blog.csdn.net/luckyapple1028/article/details/51932414

银行家算法是一种避免死锁的算法,它通过动态地分配资源来避免死锁的发生。下面是一个用C语言实现银行家算法的示例: ```c #include <stdio.h> #include <stdbool.h> #define P 5 // 进程数 #define R 3 // 资源数 int available[R] = {3, 3, 2}; // 可用资源数 int max[P][R] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}}; // 最大需求矩阵 int allocation[P][R] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}}; // 已分配矩阵 int need[P][R]; // 需求矩阵 bool finish[P] = {false}; // 进程是否完成 void calculate_need() { for (int i = 0; i < P; i++) { for (int j = 0; j < R; j++) { need[i][j] = max[i][j] - allocation[i][j]; } } } bool is_safe() { int work[R]; for (int i = 0; i < R; i++) { work[i] = available[i]; } bool finish_all = false; while (!finish_all) { bool can_allocate = false; for (int i = 0; i < P; i++) { if (!finish[i]) { bool can_finish = true; for (int j = 0; j < R; j++) { if (need[i][j] > work[j]) { can_finish = false; break; } } if (can_finish) { can_allocate = true; finish[i] = true; for (int j = 0; j < R; j++) { work[j] += allocation[i][j]; } } } } if (!can_allocate) { for (int i = 0; i < P; i++) { if (!finish[i]) { return false; } } finish_all = true; } } return true; } void request_resources(int process_id, int request[]) { for (int i = 0; i < R; i++) { if (request[i] > need[process_id][i] || request[i] > available[i]) { printf("Error: Requested resources exceed need or available.\n"); return; } } for (int i = 0; i < R; i++) { available[i] -= request[i]; allocation[process_id][i] += request[i]; need[process_id][i] -= request[i]; } if (is_safe()) { printf("Request approved. System is safe.\n"); } else { printf("Request denied. System will be unsafe.\n"); for (int i = 0; i < R; i++) { available[i] += request[i]; allocation[process_id][i] -= request[i]; need[process_id][i] += request[i]; } } } int main() { calculate_need(); int request[P][R] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; // 请求资源矩阵 int process_id; printf("Enter process ID (0-4): "); scanf("%d", &process_id); printf("Enter resource request (e.g. 1 0 2): "); for (int i = 0; i < R; i++) { scanf("%d", &request[process_id][i]); } request_resources(process_id, request[process_id]); return 0; } ``` 以上代码实现了银行家算法的主要功能,包括计算需求矩阵、判断系统是否安全、请求资源等。用户可以根据自己的需求修改进程数、资源数、可用资源数、最大需求矩阵、已分配矩阵等参数,以及根据需要添加其他功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值