[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

时间:2024-08-02 09:03:26

操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

可以操刀了—从纸上到实际

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

从Linux 0.11 那里学点东西…

读磁盘块

bread(int dev,int block){

struct buffer_head * bh;

ll_rw_block(READ,bh);

wait_on_buffer(bh);

启动磁盘读以后睡眠,等待磁盘读完由磁盘中断将其唤醒,也是一种同步

lock_buffer(buffer_head*bh)

{cli();

while(bh->b_lock)???

sleep_on(&bh->b_wait);

bh->b_lock = 1;

sti(); }

void sleep_on(struct task_struct **p){

struct task_struct *tmp;

tmp = *p;

*p = current;

current->state = TASK_UNINTERRUPTIBLE;

schedule();

if (tmp)

tmp->state=0;}

Linux 0.11 sleep_on形成的队列

sleep_on(struct task_struct **p) p 是一个指向task_struct 结构体的指针的指针

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

如何从Linux 0.11 的这个队列中唤醒?

static void read_intr(void){

... 磁盘中断

end_request(1);

end_request(int uptodate){

...

unlock_buffer(CURRENT->bh);

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

unlock_buffer(struct buffer_head * bh){

bh->b_lock=0;

wake_up(&bh->b_wait);}

schedule();

if (tmp)

tmp->state=0; 这是sleep_on 的最后三句

wake_up(struct task_struct **p){

if (p && *p) {

(**p).state=0; *p=NULL;}}

死锁处理Deadlock

死锁的成因

资源 互斥使用,一旦占有别人无法使用

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

进程 占有 了一些资源,又不释放,再去 申请 其他资源

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

各自占有的资源和互相申请的资源形成了环路等待

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

死锁的4个必要条件

互斥使用(Mutual exclusion)

资源的固有特性, 如道口

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

不可抢占(No preemption)

资源只能自愿放弃, 如车开走以后

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

请求和保持(Hold and wait)

进程必须占有资源,再去申请

循环等待(Circular wait)

在资源分配图中存在一个环路

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

死锁处理方法概述

死锁预防 "no smoking" ,预防火灾

破坏死锁出现的条件

死锁避免 检测到煤气超标时,自动切断电源

检测每个资源请求,如果造成死锁就拒绝

死锁检测+ 恢复 发现火灾时,立刻拿起灭火器

检测到死锁出现时,让一些进程回滚,让出资源

死锁忽略 在太阳上可以对火灾全然不顾

就好像没有出现死锁一样

死锁预防的方法例子

在进程执行前, 一次性申请所有需要的资源, 不会占有资源再去申请其它资源

缺点1: 需要预知未来,编程困难

缺点2: 许多资源分配后很长时间后才使用,资源利用率低

对资源类型进行排序, 资源申请必须按序进行 ,不会出现环路等待

缺点: 仍然造成资源浪费

死锁避免: 判断此次请求是否引起死锁?

如果系统中的所有进程存在一个可完成的执行序列P 1 ,…P n ,则称系统处于安全状态

都能执行完成当然就不死锁

找安全序列的银行家算法(Dijkstra 提出)

int Available[1..m]; // 每种资源剩余数量

int Allocation[1..n,1..m]; // 已分配资源数量

int Need[1..n,1..m];// 进程还需的各种资源数量

int Work[1..m]; // 工作向量

bool Finish [1..n]; // 进程是否结束

Work = Available; Finish[1..n] = false;

while(true){

for(i=1; i<=n; i++){

if(Finish[i]==false && Need[i]≤Work){

Work = Work + Allocation[i];

Finish[i] = true; break;} //T(n)=O(mn 2 )

else {goto end;}

}

}

End: for(i=1;i<=n;i++)

if(Finish[i]==false) return "deadlock";

死锁避免之银行家算法实例

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

请求出现时:首先假装分配,然后调用银行家算法

P 0 申请(0,2,0)

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

[No00003D]操作系统Operating Systems信号量的代码实现Coding Semaphore &死锁处理Deadlock

进程P 0 , P 1 , P 2 , P 3 , P 4 一个也没法执行,死锁进程组

此次申请被拒绝

死锁检测+ 恢复: 发现问题再处理

基本原因: 每次申请都执行O(mn 2 ) ,效率低。 发现问题再处理

定时检测或者是发现资源利用率低时检测

Finish[1..n] = false;

if(Allocation[i] == 0) Finish[i]=true;

...// 和Banker 算法完全一样

for(i=1;i<=n;i++)

if(Finish[i]==false)

deadlock = deadlock + {i};

选择哪些进程回滚? 优先级? 占用资源多的? …

如何实现回滚? 那些已经修改的文件怎么办?

到此:提供以前所有操作系统 doc下载

文件名 大小
[No00003D]操作系统Operating_Systems信号量的代码实现Coding_Semaphore_&死锁处理Deadlock.rar 358KB
[No00003C]操作系统Operating_Systems进程同步与信号量Processes_Synchronization_and_Semaphore.rar 297KB
[No00003A]操作系统Operating_Systems_内核级线程Kernel_Threads内核级线程实现Create_KernelThreads.rar 977KB
[No000039]操作系统Operating_Systems用户级线程User_Threads.rar 449KB
[No000038]操作系统Operating_Systems_-CPU.rar 717KB
[No000037]操作系统Operating_Systems操作系统历史与硬件概况History_of_OS_&_Summaries!.rar 287KB
[No000036]操作系统Operating_Systems系统调用的实现System_Call.rar 253KB
[No000035]操作系统Operating_System之OS_Interface操作系统接口.rar 422KB
[No000031]操作系统_Operating_Systems之Open_the_OS!.rar 308KB