Mer*_*tce 5 c++ concurrency mutex condition-variable c++11
我需要弄清楚lock和condition_variable是如何工作的.
在这里cminplusreference的-slightly modified-code中
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);
std::this_thread::sleep_for(std::chrono::seconds(1));
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();
}
Run Code Online (Sandbox Code Playgroud)
我感到困惑的是,如果worker_thread已经锁定它,主线程如何锁定互斥锁.
从这个答案我看到它是因为cv.wait 解锁互斥锁.
但是现在我对此感到困惑:那么为什么我们需要锁定它,如果cv.wait解锁呢?
例如,我可以这样做吗?
std::unique_lock<std::mutex> lk(m, std::defer_lock);
Run Code Online (Sandbox Code Playgroud)
所以,我创建了锁对象,因为cv需要它,但我在创建时不会锁定它.
现在有什么不同吗?
我不明白为什么我收到"运行时错误" 这里在这种情况下.
我将尝试添加更多关于为什么条件变量需要锁的解释。
您必须拥有锁,因为您的代码需要检查条件谓词是否为真。谓词是某个值或值的组合,必须为 true 才能继续。它可以是 NULL 指针或指向可供使用的完整数据结构。
您必须在等待之前锁定它并检查谓词,因为当您开始等待条件时,另一个线程可能已经设置了它。
条件通知和等待返回并不意味着条件为真。它仅意味着该条件在某个时候为真。它甚至可能是真的,然后又是假的,然后又是真的。这也可能意味着您的线程处于不相关的信号处理程序中,导致条件等待爆发。您的代码甚至不知道条件通知已被调用多少次。
因此,一旦条件等待返回,它就会锁定互斥体。现在,您的代码可以在安全地锁在锁中时检查情况。如果为 true,则代码可以更新它需要更新的内容并释放锁。如果不是真的,它就会返回到条件等待重试。例如,它可以获取该数据结构指针并将其复制到向量中,然后将受锁保护的指针设置回 NULL。
将条件视为提高轮询循环效率的一种方法。您的代码仍然必须完成它在循环等待中运行时要做的所有事情,除了它可以进入睡眠状态而不是不停地旋转。
| 归档时间: |
|
| 查看次数: |
3208 次 |
| 最近记录: |