操作系统在设计时考虑到了避免死锁的情况,避免死锁的主要方法包括以下几个方面:
- 破环资源申请等待环路
对于资源申请等待环路,通过破环来避免死锁。具体做法是通过引入资源顺序的概念,要求每个进程按照固定的顺序申请资源,从而避免环路的产生。
示例代码:
// 破环资源申请等待环路
// 假设A、B、C三个进程,它们依次访问资源1、2、3。
// A申请到资源1后,会按照先申请2,再申请3的顺序申请资源。
// B申请到资源2后,也会按照先申请3、再申请1的顺序申请资源。
// C申请到资源3后,也会按照先申请1、再申请2的顺序申请资源。
int request1, request2, request3;
bool finish1 = false, finish2 = false, finish3 = false;
while (!finish1 || !finish2 || !finish3) {
if (!finish1 && request1 <= (request2 + request3)) {
// 申请资源1
...
// 释放资源1
finish1 = true;
}
if (!finish2 && request2 <= (request3 + request1)) {
// 申请资源2
...
// 释放资源2
finish2 = true;
}
if (!finish3 && request3 <= (request1 + request2)) {
// 申请资源3
...
// 释放资源3
finish3 = true;
}
}
- 破环资源持有与等待环路
对于资源持有与等待环路,可以要求进程在申请资源之前释放已经占有的资源,然后重新申请所有需要的资源,从而破坏持有和等待的环路。
示例代码:
// 破环资源持有与等待环路
// 假设A、B两个进程,它们分别占有了资源1和资源2,然后互相申请对方占有的资源。
// 如果A、B同时发起申请,操作系统会根据优先级给其中一个申请加锁,而另一个进程则需要释放已经占有的资源重新申请所有需要的资源。
// A在申请资源2之前需要释放资源1,然后重新申请资源1和资源2。
// B在申请资源1之前需要释放资源2,然后重新申请资源1和资源2。
class Resource {
...
};
class Process {
public:
void acquire(Resource* resource) {
// 申请资源
...
held_resources.push_back(resource);
}
void release(Resource* resource) {
// 释放资源
...
held_resources.erase(std::remove(held_resources.begin(), held_resources.end(), resource), held_resources.end());
}
void request(Resource* resource) {
// 申请资源
...
// 成功获取资源
acquire(resource);
}
private:
std::vector<Resource*> held_resources;
};
Process p1, p2;
Resource r1, r2;
// 线程1占用资源1,然后请求资源2
p1.acquire(&r1);
p1.request(&r2);
// 线程2占用资源2,然后请求资源1
p2.acquire(&r2);
p2.request(&r1);
以上就是我对于操作系统避免死锁的攻略,提供了两个示例代码方便理解。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:操作系统如何避免死锁? - Python技术站