#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
std::mutex mutex1;
std::mutex mutex2;
std::condition_variable cv;
int buffer;
bool notify;
void task(std::string threadName, int loopmax) {
for(int i = 0; i < loopmax; i++) {
mutex1.lock();//normal lock for both threads
buffer++;
std::cout << threadName << buffer << "\n";
mutex1.unlock();//normal unlock for both threads
}
}
int main() {
std::thread thr1([&] {
std::unique_lock<std::mutex> lock(mutex2);//unique_lock in working_thread
for(int j = 0; j < 3; j++) {
task("working_thread: ", 50);
}
notify = true;
std::cout << "worker complete\n";
cv.notify_one();
});
task("Main_thread: ", 50);//can I do the task-functions here?
task("Main_thread: ", 50);
std::unique_lock<std::mutex> lock(mutex2);//unique_lock in main_thread
//if I use the task-function here, the threads don't interlink anymore
if(!notify) {
cv.wait(lock);
}
printf("Hallo\n");
thr1.join();
return 0;
}
我总是以这种方式获得两个线程的良好相互链接输出。 如果Working_thread锁定其unique_lock和 MAIN_THREAD锁定smutex1在任务功能中? 它也可以在其他地方造成一个死锁吗?
从
僵局需要四个条件:相互排斥,保持和等待,没有先发制人和循环等待。
无论您使用唯一的锁或普通锁,任何符合四个条件的等待操作都可能导致僵局。 当前代码无法满足僵局条件
正如@mestkon在评论中指出的那样,在您的代码中,每个线程当前仅使用一个互斥X,因此不可能满足“
hold和watch”条件。因此,不会发生任何僵局。定义锁定序列
通常一种简单的实用方法是定义锁定序列并在各处使用。
例如,如果您曾经需要mutex1
和
mutex2
同时,请确保始终锁定mutex1
首先,然后mutex2
第二(或始终相反)。
因此,您可以轻松防止“ circular wate”(
mutex1
等待mutex2
和等待mutex2
)条件,因此不会发生任何僵局。