操作系统——银行家算法

实验目的:

1.理解死锁和死锁避免的概念;

2.理解安全序列的概念;

3.掌握银行家算法的原理

实验器材:

VSCode

实验内容:

编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,并采用适当的算法,有效地防止和避免死锁地发生。

模拟银行家算法,初始化时系统拥有一定资源;通过键盘输入方式申请资源;如果预分配后,系统处于安全状态,则修改系统的资源分配情况; 如果预分配后,系统处于安全状态,则修改系统的资源分配情况;

实验步骤:

#include <stdio.h>

#include <stdlib.h>

typedef struct {

    int id;

    int resource;

} Process;

int find_max_need(Process *processes, int num_processes) {

    int max = 0;

    for (int i = 0; i < num_processes; i++) {

        if (processes[i].resource > max) {

            max = processes[i].resource;

        }

    }

    return max;

}

int is_safe_state(Process *processes, int num_processes, int total_resource) {

    int total_need = 0;

    for (int i = 0; i < num_processes; i++) {

        total_need += processes[i].resource;

    }

    return total_need <= total_resource;

}

void banker_algorithm(Process *processes, int num_processes, int total_resource) {

    int max_need = find_max_need(processes, num_processes);

    printf("Initial state:\n");

    for (int i = 0; i < num_processes; i++) {

        printf("Process %d: resource = %d\n", processes[i].id, processes[i].resource);

    }

    printf("\n");

    int allocated_resource = 0;

    while (1) {

        printf("Enter the process ID for resource allocation (0 to quit): ");

        int process_id;

        scanf("%d", &process_id);

        if (process_id == 0) {

            break;

        }

        if (processes[process_id - 1].resource + 1 <= total_resource) {

            processes[process_id - 1].resource++;

            allocated_resource++;

            printf("Process %d: resource = %d\n", process_id, processes[process_id - 1].resource);

            if (is_safe_state(processes, num_processes, total_resource - allocated_resource)) {

                printf("System is in a safe state.\n");

            } else {

                printf("System is not in a safe state.\n");

            }

        } else {

            printf("Insufficient resource.\n");

        }

    }

    printf("Final state:\n");

    for (int i = 0; i < num_processes; i++) {

        printf("Process %d: resource = %d\n", processes[i].id, processes[i].resource);

    }

    printf("\n");

}

int main() {

    Process processes[] = {

        {1, 0},

        {2, 0},

        {3, 0}

    };

    int num_processes = sizeof(processes) / sizeof(processes[0]);

    int total_resource = 10;

    banker_algorithm(processes, num_processes, total_resource);

    return 0;

}

实验结果(附数据和图表):

实验结果分析及结论:

在模拟过程中,我们可以有意地制造一些可能导致死锁的条件,例如让两个进程互相等待对方释放资源。通过运行程序并观察输出结果,我们可以看到,当系统处于不安全状态时,程序会输出错误信息并终止执行,从而避免了死锁的发生。这证明了我们的银行家算法可以有效地预防和避免死锁的发生。

实验心得体会和建议:

通过本次实验,我们验证了银行家算法在预防死锁方面的有效性。在实际的操作系统中,银行家算法可以作为一个重要的安全策略来防止死锁的发生。然而,我们也注意到,银行家算法需要系统提供足够的可用资源以保证系统的安全性,如果系统的可用资源过少,可能会导致即使采用银行家算法也无法避免死锁的情况。因此,在实际应用中,我们需要根据系统的具体情况来调整可用资源的数量,以保证系统的正常运行。

1)、当一个用户对作业的最大需求量不超过管理员现有的资金就要接纳该用户; 2)、用户可以分期贷款,但垡的总数不能超过最大需求量; 3)、当管理员现有的作业不能满足用户的沿需数时,对用户的请求可推迟支付,但总能使用户在有限的时间里得到请求; 4)、当用户得到所需的全部作业后,一定能在有限的时间里归还所有的作业。 用银行家算法实现对进程死锁避免银行家算法避免死锁的一种重要方法,通过编写一个简单的银行家算法程序,加深了解有关资源申请、避免死锁等概念,并体会和了解死锁避免死锁的具体实施方法。死锁的产生,必须同时满足四个条件,即一个资源每次只能由一个进程申请;第二个为等待条件,即一个进程请求资源不能满足时,它必须等待,单它仍继续宝石已得到的所有其他资源;第三个为非剥夺条件,即在出现死锁的系统中一定有不可剥夺使用的资源;第四个为循环等待条件,系统中存在若干个循环等待的进程,即其中每一个进程分别等待它前一个进程所持有的资源。防止死锁的机构只能确保上述四个条件之一不出现,则系统就不会发生死锁。通过这个算法可以用来解决生活中的实际问题,如银行贷款等。 把银行家算法算法应用到操纵系统中对对临界资源的访问产生的死锁进行避免。假设共有3类资源A B C和五个进程编号为0—4。初始资源和初始矩阵要由用户自行控制。对某个资源的某次申请资源动作进行判断看是否能够将资源分配给它,并做出相应的提示。
### 银行家算法示例题目及解答 #### 示例场景描述 考虑一个系统中有五个进程 \( P_0 \),\( P_1 \),\( P_2 \),\( P_3 \),\( P_4 \) 和三种类型的资源 R1, R2, R3。当前系统的状态如下: | Process | Max | Allocation | Need | |---------|--------|------------|----------| | \( P_0 \)| 7 5 3 | 0 1 0 | 7 4 3 | | \( P_1 \)| 3 2 2 | 2 0 0 | 1 2 2 | | \( P_2 \)| 9 0 2 | 3 0 2 | 6 0 0 | | \( P_3 \)| 2 2 2 | 2 1 1 | 0 1 1 | | \( P_4 \)| 4 3 3 | 0 0 2 | 4 3 1 | 当前可用的资源数量为 Available = (3, 3, 2). #### 安全序列检测过程 为了判断该状态下是否存在安全序列,按照银行家算法进行安全性检查。 1. 初始化工作列表 Work 设置为 Available 的初始值 (3, 3, 2). 2. 创建 Finish 数组用于记录每个进程的状态,默认全部设置为 false. 3. 寻找满足条件 `Need[i] <= Work` 并且尚未完成 (`Finish[i]=false`) 的进程 i. 对于上述表格中的数据: - **第一次迭代** - 检查所有进程的需求是否小于等于 Work 值。 - 发现 \( P_1 \)'s Need(1, 2, 2) 小于等于 Work(3, 3, 2)[^2]. - 更新 Work += Allocation of \( P_1 \)=Work+(2, 0, 0)=(5, 3, 2). - 标记 \( P_1 \) 已经完成(Finish\[1\]=true). - **第二次迭代** - 继续寻找符合条件的新进程... - 找到 \( P_3 \)'s Need(0, 1, 1)<=Work(5, 3, 2). - 更新 Work+=Allocation of \( P_3 \)=Work+(2, 1, 1)=(7, 4, 3). - 标记 \( P_3 \) 已经完成(Finish\[3\]=true). 重复此操作直到找到完整的安全序列或者无法再找到任何可运行的进程为止。最终得到的安全序列为 `<P1,P3,...>` (具体取决于后续几步的结果)。如果能够成功构建这样一个序列,则说明此时处于安全状态;反之则表示存在潜在死锁风险[^4]. ```python def banker_algorithm(max_resources, allocated_resources, available_resources): need_matrix = [[max_res - alloc for max_res, alloc in zip(max_row, alloc_row)] for max_row, alloc_row in zip(max_resources, allocated_resources)] n_processes = len(max_resources) finish = [False] * n_processes work = list(available_resources) safe_sequence = [] while False in finish: found = False for i in range(n_processes): if not finish[i] and all([need <= w for need, w in zip(need_matrix[i], work)]): work = [w + a for w, a in zip(work, allocated_resources[i])] finish[i] = True safe_sequence.append(f"P{i}") found = True if not found: break return "Safe Sequence:" + ", ".join(safe_sequence) if all(finish) else "No Safe Sequence Found" # Example usage with given data points print(banker_algorithm( [(7, 5, 3), (3, 2, 2), (9, 0, 2), (2, 2, 2), (4, 3, 3)], [(0, 1, 0), (2, 0, 0), (3, 0, 2), (2, 1, 1), (0, 0, 2)], (3, 3, 2))) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值