/// @author zhaolu
/// @date 2020/04/16
#include <iostream>
#include <atomic> // std::atomic_flag
#include <thread> // std::thread std::this_thread
#include <chrono> // std::chrono::seconds
std::atomic_flag print = ATOMIC_FLAG_INIT;
void fun(int id, std::atomic_flag *flag_1, std::atomic_flag *flag_2) {
while(print.test_and_set());
std::cout << "thread " << id << " request resources " << flag_1 << std::endl;
print.clear();
while (flag_1->test_and_set())
;
while(print.test_and_set());
std::cout << "thread " << id << " get resources " << flag_1 << std::endl;
print.clear();
std::this_thread::sleep_for(std::chrono::seconds(1));
while(print.test_and_set());
std::cout << "thread " << id << " request resources " << flag_2 << std::endl;
print.clear();
while(flag_2->test_and_set())
;
while(print.test_and_set());
std::cout << "thread " << id << " get resources " << flag_2 << std::endl;
print.clear();
// do something
flag_1->clear();
while(print.test_and_set());
std::cout << "thread " << id << " release resources " << flag_1 << std::endl;
print.clear();
flag_2->clear();
while(print.test_and_set());
std::cout << "thread " << id << " release resources " << flag_2 << std::endl;
print.clear();
}
int main() {
std::atomic_flag flag_1 = ATOMIC_FLAG_INIT;
std::atomic_flag flag_2 = ATOMIC_FLAG_INIT;
std::thread thread_1(fun, 1, &flag_1, &flag_2);
std::thread thread_2(fun, 2, &flag_2, &flag_1);
thread_1.join();
thread_2.join();
return 0;
}
flag_1 => resource_1
flag_2 => resource_2
输出结果为:
:./main
thread 1 request resources 0x7ffeef93e998
thread 1 get resources 0x7ffeef93e998
thread 2 request resources 0x7ffeef93e990
thread 2 get resources 0x7ffeef93e990
thread 1 request resources 0x7ffeef93e990
thread 2 request resources 0x7ffeef93e998
无反应。。
死锁的条件
-
互斥条件:一个资源每次只能被一个进程使用,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
-
请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
-
不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能 由获得该资源的进程自己来释放(只能是主动释放)。
-
循环等待条件: 若干进程间形成首尾相接循环等待资源的关系