C++标准库condition_variable的示范及解释

简单的写一个对condition_variable的解释,如果有错误可以请大家纠正。
如果想学习condition_varible,首先要有前置知识:thread线程,mutex互斥信号量,以及unique_lock和guard_lock。
当我看一些博客介绍的时候,还是有一些云里雾里,因为大多数博客并没有一个很直观的运行顺序,本篇博客也是参考一篇文章:

C++11(六) 条件变量(condition_variable) - 知迷途的文章 - 知乎
https://zhuanlan.zhihu.com/p/224054283

加上自己利用时间输出才大致了解了什么是condition_varable。
接下来是代码部分(可以在win和linux下运行,已经测试过),以及一个示范输出(不通电脑可能有不同的输出,但是时间大致是相同的),以及对代码异步运行的解释。

代码部分

/**
* 如何运行本代码,假如本代码的名字为cv.cpp,请使用以下编译命令:
* Linux: "g++ cv.cpp -lpthread -o cv" 
* Win:   "g++ cv.cpp -lpthread -o cv.exe"
* 
*/
// condition_variable example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
uint32_t beg;
bool ok;
std::mutex m;
std::condition_variable cv;
std::mutex priLock;
double getms(int beg)
{
	//获取当前运行时间与beg时间戳的时间差
    return (double)(clock()-beg)/CLOCKS_PER_SEC*1000;
}
void pri(std::string& id,int typ)
{
    std::lock_guard<std::mutex> l(priLock);
    printf("id:%s typ:%d %.2lf ms\n",id.c_str(),typ,getms(beg));
}
void sleep(double t)
{
	//模拟实现的一个1通用休眠,t的单位为ms,sleep(100)表示休眠100ms
    int beg=clock();
    while(getms(beg)<=t);
}

void test(std::string id)
{
    std::unique_lock<std::mutex> lm(m);
    pri(id,0);
    sleep(200);
    pri(id,1);
    cv.wait(lm,[]()->bool{return ok;});
    pri(id,2);
}
int main ()
{
    beg=clock();
    std::thread t(test,"test");
    sleep(50);
    std::string typ="main";
    {
        pri(typ,0);
        std::unique_lock<std::mutex> lm(m);
        pri(typ,1);
        ok=true;
        sleep(50);
        pri(typ,2);
        cv.notify_one();
        sleep(100);
        lm.unlock();
        sleep(100);
    }
    t.join();
    return 0;
}

代码输出及解释

/*输出示例:
id:test typ:0 0.00 ms
id:main typ:0 51.00 ms
id:test typ:1 203.00 ms
id:main typ:1 208.00 ms
id:main typ:2 260.00 ms
id:test typ:2 358.00 ms
*/
/**
 * test在0ms开始运行,运行到32行将m进行上锁,主进程休眠50ms在51ms左右运行到47行,
 * 此时m被上锁,main线程被阻塞
 * 
 * test线程在34休眠200ms后,在203ms运行到36行,此时test线程会调用条件变量cv进行wait
 * (直到有人发送notify信息,并且ok被设置为true),同时会将m的锁unlock
 * 
 * 在5ms后,也就是208ms,main线程发现m已经被解锁,此时开始继续从47行开始运行,
 * 并在49行将ok设置为true
 * 
 * 可以看到我们208ms已经将ok设置为true,但是可以看到test线程并没有在208ms左右被唤醒,
 * 还被阻塞在wait处(36行)
 * 
 * 在main线程处,50行休眠了50ms,在260ms对cv变量进行了notify_one,此时test线程在36行
 * 处会收到信息,并检查发现ok被设置为true。
 * 但此时互斥锁m还被锁着所以还不能继续运行,当53行(main线程休眠100ms)运行结束,并且54行
 * 执行了lm.unlock()对互斥锁m解锁后,test线程才能运行
 * 
 * 重点:
 * 调用cv.wait后会对锁进行unlock,并被阻塞。
 * 只有当ok被设置为true,并且发送notify_one信息后,
 * 同时互斥锁背unlock后,cv.wait处才能继续向下运行
 * 
 * 
 */
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值