据我所知,当我构造一个新的thread
时,它立即开始执行。
所以我想知道,cv.wait(lk, []{return ready;});
中的worker_thread()
和std::lock_guard<std::mutex> lk(m);
中的main
是否会同时锁定互斥锁?这会发生吗?
(从cppreference中,我知道std::condition_variable::wait
和std::lock_guard
将在构造期间锁定互斥锁。)
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex m;
std::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;
void worker_thread()
{
// Wait until main() sends data
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return ready;});
// after the wait, we own the lock.
std::cout << "Worker thread is processing data\n";
data += " after processing";
// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completed\n";
// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
}
int main()
{
std::thread worker(worker_thread);
data = "Example data";
// send data to the worker thread
{
std::lock_guard<std::mutex> lk(m);
ready = true;
std::cout << "main() signals data ready for processing\n";
}
cv.notify_one();
// wait for the worker
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return processed;});
}
std::cout << "Back in main(), data = " << data << '\n';
worker.join();
}
答案 0 :(得分:3)
Mutex旨在获取资源锁,只有1个线程可以获取该锁。互斥锁的锁定是原子的,两个线程无法获得互斥锁的锁,如果可以的话,那么就无法实现互斥锁的目的!
Mutexes的构建使锁定是一项原子操作:无论一次尝试锁定多少线程,它一次只能在一个线程上完成
答案 1 :(得分:1)
“ Mutex”是“互斥”的缩写;目的是在任何时候仅允许一个线程锁定互斥锁。
也就是说,该示例中存在一个严重的问题。它有潜在的死锁,因为它会尝试对固有的非顺序操作进行排序。
如果main
经历了其锁定代码,将ready
设置为true
,并在新线程锁定互斥锁并调用{{1 }}。如果发生这种情况,当新线程位于notify()
中时,wait()
将继续其对main
的调用,并且没有人通知另一个。他们俩都在等待对方做某事。
如果您不走运,则在测试代码时不会看到此内容。新线程可能会在主线程调用wait()
之前开始运行到wait()
,然后代码将按预期工作。这很不幸,因为它迟早会锁定,很可能是在向最重要的客户演示代码时出现的。