7. 等待一个事件

等待一个事件

在多线程开发中,当一个线程的运行条件是另外一个线程的运算结果的时间,等待线程通常有几种处理方法1. 循环查询,知道满足条件为止 2. 休眠一个固定的时间,然后查询条件,当不满足的时候再继续休眠相同时间,知道下一次查询满足条件 3. 使用条件变量
下面分别对后两种方法进行阐述


  1. 休眠固定时间
    使用std::sleep_for()进行周期性的间歇

    bool flag
    mutex m;
    void wait_for(){
      unique_lock<mutex>uloc(m);
      while(!flag){
        uloc.unlock();
    	this_thread::sleep_for(chrono::nilliseconds(100));
    	uloc.lock();
      }
    }
    

这种方法的优缺点也很直觉,优点:代码简单易懂,缺点:睡眠的时间难以掌握


  1. 使用条件变量
    C++标准库对于条件变量有两套实现:std::condition_variablestd::condition_variable_any两个实现都包含在头文件<condition_variable>中,两者都需要一个互斥量才能工作,前者仅能和mutex一起工作,而后者可以和各种互斥量进行工作,因为后者更加通用,所以导致从体积,性能,以及系统资源等方面有着更大的消耗,在一般的开发过程中,前者为首选类型,当系统对于灵活性有着硬性要求的时候才考虑后者
    下面的代码展示了condition_variable的基本使用:

    mutex m;
    queue<int>que;
    condition_variable que_cond;
    void data_prepare_thread(){
      while(more_prepare_data()){
        auto data = prepare_data();
        lock_guard<mutex>loc(m);
        que.push(data);
        que_cond.notify_once();
      }
    }
    void data_process_thread(){
      while(true){
        unique_lock<mutex>lk(m);
        que_cond.wait(lk,[&que](){return !que.empty();});
        auto data = que.front();
        que.pop();
        lk.unlock();
        process(data);
        if(is_lask_chunk(data))
          break;
      }
    }
    

对于生产者,首先对共享资源上锁,然后将准备的数据添加进入共享资源,最后调用condition_variable中的notify_one()成员函数对等待的线程进行通知
对于消费者,首先对共享资源上锁,调用condition_variable中的wait方法,wait首先回去检查第二参数是否满足条件,如果满足则继续持有锁,进行下面的操作,如果不满足条件则释放锁,然后置于阻塞或者等待状态,知道进程被唤醒。
注意,不一定是另一个线程调用notify的时候wait状态才会被唤醒,某些条件下wait状态的线程也会被唤醒,这就是所谓的伪唤醒,因此判断条件的合适性显得尤为重要。

原文链接: https://www.cnblogs.com/hhyandcpp/p/17040786.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    7. 等待一个事件

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/311097

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 上午11:51
下一篇 2023年2月16日 上午11:52

相关推荐