一、实验目的
本次实验旨在通过对死锁的原理及避免方法进行探究,以进一步提高学生的操作系统相关知识和技能,为后续的实验和实际工作打下基础。
二、实验原理
死锁是指在多个并发任务中,由于彼此互相占用所需的资源而导致系统陷入无限等待的一种状态。当同时发生以下四个条件时,系统将会陷入死锁状态:
1. 互斥条件:进程对所分配到的资源具有排它性,即一个资源每次只能被一个进程使用。
2. 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程阻塞,但又对已获得的其他资源保持不放。
3. 不剥夺条件:已分配的资源在未使用完之前,不可被其他进程强行夺走,即只有该占用该资源的进程自己可将该资源释放。
4. 环路等待条件:系统中若干进程形成一种头尾相接的环形等待资源关系。
三、实验设备
操作系统:Windows 10
编程语言:C++11
四、实验步骤
1. 定义进程和资源
首先,在代码中定义进程和资源,代码如下:
```
const int n = 4; // 进程数和资源数
const int m = 3;
int Available[m] = {3, 3, 2}; // 系统资源数
int Max[n][m] = { // 最大需求矩阵
{7, 5, 3},
{3, 2, 2},
{9, 0, 2},
{2, 2, 2}
};
int Allocation[n][m] = {0}; // 已分配矩阵
int Need[n][m] = { // 需求矩阵
{4, 3, 1},
{1, 1, 2},
{3, 0, 2},
{2, 3, 0}
};
```
2. 实现银行家算法
由于银行家算法能够很好地解决死锁问题,所以本实验主要是对银行家算法的实现。具体方法如下:
(1)循环遍历所有进程,找到一个未被标记(即未被放入安全序列中)的进程,并满足其需求小于等于当前系统资源时,标记该进程并将其放入安全序列中。
```
bool flag[n] = {false}; // 标记矩阵,标记进程是否被放入安全序列
int Work[m] = {0}; // 可用资源
int SafeOrder[n] = {0}; // 安全序列
int cnt = 0; // 安全序列的长度
for (int i = 0; i < m; i++) {
Work[i] = Available[i];
}
while (cnt < n) {
bool foundProcess = false;
for (int i = 0; i < n; i++) {
if (!flag[i]) {
bool enoughResources = true;
for (int j = 0; j < m; j++) {
if (Need[i][j] > Work[j]) {
enoughResources = false;
break;
}
}
if (enoughResources) {
foundProcess = true;
for (int j = 0; j < m; j++) {
Work[j] += Allocation[i][j];
}
SafeOrder[cnt++] = i;
flag[i] = true;
}
}
}
}
```
(2)如果所有进程都被标记,那么该状态是安全状态,否则它是不安全状态。
```
bool isSafe = true;
for (int i = 0; i < n; i++) {
if (!flag[i]) {
isSafe = false;
break;
}
}
if (isSafe) {
cout << "安全序列为:";
for (int i = 0; i < n; i++) {
cout << SafeOrder[i] << " ";
}
cout << endl;
} else {
cout << "当前状态不安全!" << endl;
}
```
五、实验结果
在本次实验进行过程中,我们通过定义进程和资源以及实现银行家算法等方式,成功地避免了死锁的发生,从而保证了系统的安全性和稳定性。
六、实验总结
通过本次实验,我了解了死锁的概念、原理和条件,并深入掌握了避免死锁的方法,进一步提高了操作系统和编程方面的技能。同时,本次实验还提醒我们,在日常实际工作和学习中,要注意合理进行资源的管理和分配,避免出现死锁等情况,从而保证工作效率和系统的正常运行。
扫码咨询 领取资料