为什么lock_guard可以通过unique_lock获得一个已经锁定的互斥锁?-仍然有问题
why lock_guard can get an already locked mutex by unique_lock? - still questions
我正在研究这个例子。我找到了这个问题,并以为我会得到答案,但我仍然有一个问题。
为了方便,我把代码贴在这里:
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::cout << "------------------------n";
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 datan";
data += " after processing";
// Send data back to main()
processed = true;
std::cout << "Worker thread signals data processing completedn";
// 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 processingn";
}
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();
return 0;
}
语句std::unique_lock<std::mutex> lk(m);
不应该阻塞主线程,因为互斥体m
被worker_thread
锁定?如果是,在这个例子中,它后面的语句cv.wait(lk, []{return processed;});
不是不必要的吗?当主线程可以锁定互斥锁时,processed
已经为true。
调用wait
将在等待期间解锁互斥锁。参见http://en.cppreference.com/w/cpp/thread/condition_variable/wait。
编辑:这在你链接到的问题的答案中明确说明:https://stackoverflow.com/a/32030975/212870
EDIT 2:"当主线程可以锁定互斥锁时,processed
将已经为真"是不正确的。工作线程可能还没有启动,或者即使启动了,也可能没有看到ready
设置。
如果ready
是false
, cv.wait(lk, []{return ready;});
行执行以下操作:
-
解锁互斥锁
lk
-
阻塞等待通知的线程
-
当通知到达时,解除线程阻塞并锁定互斥锁
lk
因此主线程不会阻塞std::lock_guard<std::mutex> lk(m);
,因为互斥锁被工作线程解锁了。
相关文章:
- 如何找到锁定Linux futex的C++行
- G锁定铸造到基础上会释放模拟行为
- 如何检查线程是否锁定
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 我应该在锁定TBitmap画布后解锁它吗
- 尝试构建"lock-free"数据结构C++
- C++ 11 中的锁定是否保证访问数据的新鲜度?
- 在两个线程上读/写 64 位,无互斥/锁定/原子
- 如何在实时应用程序中锁定线程
- 为什么 c++11 std::lock 和 std::scoped_lock 至少需要 2 个参数?
- 为什么"weak.lock()"返回"nullptr" "auto weak=std::make_shared<int>(42);"的定义?
- 在 lambda 中锁定 std::shared_ptr 的复制操作
- DRD 报告"conflicting load" std::mutex::lock 上的错误
- 使用简单两相锁定的并发程序
- 锁定来自其他线程的类成员
- 他们如何将红外锁定像素转换为镜头前方 1m 的正常平面上的位置
- 同一互斥锁顺序上的锁定和解锁是否一致?
- 在任何地方对C++中所有并行线程中的所有锁定和解锁实例使用相同的 std::mutex 和 lock 对象
- mutex::lock() 检查一次解锁状态是否已经被另一个线程锁定?
- RocksDB IO错误:锁定db/lock:没有可用的锁