Pas*_*cal 5 condition-variable c++11
我不确定我是否真的理解为什么std::condition_variable需要额外std::mutex的参数?它不应该被自己锁定吗?
#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
std::condition_variable cv;
std::mutex cv_m;
int i = 0;
bool done = false;
void waits()
{
std::unique_lock<std::mutex> lk(cv_m);
std::cout << "Waiting... \n";
cv.wait(lk, []{return i == 1;});
std::cout << "...finished waiting. i == 1\n";
done = true;
}
void signals()
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "Notifying falsely...\n";
cv.notify_one(); // waiting thread is notified with i == 0.
// cv.wait wakes up, checks i, and goes back to waiting
std::unique_lock<std::mutex> lk(cv_m);
i = 1;
while (!done)
{
std::cout << "Notifying true change...\n";
lk.unlock();
cv.notify_one(); // waiting thread is notified with i == 1, cv.wait returns
std::this_thread::sleep_for(std::chrono::seconds(1));
lk.lock();
}
}
int main()
{
std::thread t1(waits), t2(signals);
t1.join();
t2.join();
}
Run Code Online (Sandbox Code Playgroud)
其次,在示例中,他们首先解锁互斥锁(signals方法).他们为什么要这样做?不要先断开锁定,然后在通知后解锁?
互斥锁保护谓词,也就是你正在等待的东西。由于您正在等待的东西必须在线程之间共享,因此必须以某种方式对其进行保护。
在你上面的例子中,i == 1是谓词。互斥锁保护i.
退后一步思考为什么我们需要条件变量可能会有所帮助。一个线程检测到一些阻止它前进的状态,并且需要等待其他某个线程更改该状态。这种状态检测必须在互斥锁下进行,因为必须共享状态(否则,另一个线程如何更改该状态?)。
但是线程不能释放互斥锁然后等待。如果在互斥锁释放之后但在线程设法等待之前状态发生了变化怎么办?所以你需要一个原子的“解锁和等待”操作。这就是条件变量提供的具体内容。
没有互斥锁,他们会解锁什么?
选择在释放锁之前还是之后给条件变量发信号是一个复杂的事情,双方都有好处。一般来说,如果在持有锁的同时发出信号,您将获得更好的性能。
| 归档时间: |
|
| 查看次数: |
1024 次 |
| 最近记录: |