std::condition_variable 条件变量可以履行发送者或接收者的角色,作为发送者,它可以通知一个或多个接收者。
条件变量允许我们通过通知进而实现线程同步。
举例:
// std::condition_variable
//当 std::condition_variable对象的某个wait 函数被调用的时候,它使用 std::unique_lock(通过 std::mutex) 来锁住当前线程。
//当前线程会一直被阻塞,直到另外一个线程在相同的 std::condition_variable 对象上调用了 notification 函数来唤醒当前线程
class CCondition_variable
{
public:
CCondition_variable() {}
~CCondition_variable() {}
void Run();
void Printf_ID(int nThreadID);
void GoWork();
private:
std::mutex mtx; // 全局互斥锁.
std::condition_variable cv; // 全局条件变量.
bool ready = false; // 全局标志位.
};
void CCondition_variable::Run()
{
printf("========std::condition_variable==========\n");
std::thread threads[10];
for (int i = 0; i < 10; i++)
{
threads[i] = std::thread(std::bind(&CCondition_variable::Printf_ID, this, i));
}
printf("[std::condition_variable] 10 threads ready to race...\n");
GoWork();
for (auto& th : threads)
{
th.join();
}
}
void CCondition_variable::Printf_ID(int nThreadID)
{
std::unique_lock <std::mutex> lck(mtx);
while (!ready) // 如果标志位不为 true, 则等待...
{
printf("[std::condition_variable] 线程编号:%d\n",nThreadID);
cv.wait(lck); // 当前线程被阻塞, 当全局标志位变为 true 之后
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
printf("[std::condition_variable] 全局标志位变为true之后,线程编号:%d\n", nThreadID);
}
// 线程被唤醒, 继续往下执行打印线程编号id.
printf("[std::condition_variable] 线程 %d 被唤醒\n", nThreadID);
}
void CCondition_variable::GoWork()
{
printf("[std::condition_variable] GoWork begin...\n");
std::unique_lock <std::mutex> lck(mtx);
ready = true; // 设置全局标志位为 true.
cv.notify_all(); // 唤醒所有线程.
printf("[std::condition_variable] GoWork end...\n");
}
int main()
{
std::shared_ptr<CBase> pCondition_variable = std::make_shared<CCondition_variable>();
pCondition_variable->Run();
return 0;
}
运行结果: