C++多线程编程之condition_variable

参考www.cplusplus.com

std::condition_variable

条件变量可以阻塞调用线程,直至有通知到来(notified)。
当条件变量的某个wait函数被调用时,该函数将使用一个管理mutex对象的unique_lock来锁住当前线程。当前线程将被阻塞,直至使用了同一个条件变量的另外一个线程调用了notification函数中的一个。
condition_variable总是使用unique_lock<mutex>,而condition_variable_any可以和任意的锁类型配合使用。

构造函数

condition_variable();
condition_variable (const condition_variable&) = delete;

构造一个condition_variable对象,不支持拷贝和移动操作。

析构函数

~condition_variable();

销毁condition_variable对象。任何被阻塞在这个条件变量上的线程都应该在调用析构函数之前被notified;而调用析构函数之后,任何线程都不应该再调用wait函数。

condition_variable::notify_all

void notify_all() noexcept;

唤醒当前所有因等待该条件变量而阻塞的线程;若没有线程等待,则什么也不做。

condition_variable::notify_one

void notify_one() noexcept;

功能与notify_all相同,区别在于如果有多个等待线程,则随机选择其中一个线程唤醒。

condition_variable::wait

void wait (unique_lock<mutex>& lck);
template <class Predicate>
  void wait (unique_lock<mutex>& lck, Predicate pred);

当前线程应该对lck管理的mutex上锁,并且被阻塞直至收到通知(notified)。
阻塞当前线程的同时,该函数会自动调用lck.unlock()函数,并允许其他被阻塞线程继续运行。
一旦被其他线程通知,该函数将解除阻塞并调用lck.lock(),恢复lck状态至刚调用该函数时的状态,然后函数将返回。需要注意的是,在返回之前,最后一次对mutex上锁可能会再次阻塞当前线程。

通常,其他线程调用notify_onenotify_all会唤醒该函数,但有时这两个函数都没被调用也会产生一个通知,即虚假唤醒。因此,wait函数的使用者需确保
重新开始的条件都得到满足。

如果谓词pred被指定,在该函数只有在pred返回false时才会阻塞当前线程,并且收到通知后只有在pred返回true时才能解除阻塞。第二种用法可以用于防止虚假唤醒,其执行过程如下:

while(!pred())
	wait(lck);

pred是没有形参的可调用对象或函数,并返回可转换为bool类型的值。该pred会被重复调用直至返回值为true

condition_variable::wait_for

//无条件版本
template <class Rep, class Period>
  cv_status wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time);
//有条件版本
template <class Rep, class Period, class Predicate>
       bool wait_for (unique_lock<mutex>& lck,
                      const chrono::duration<Rep,Period>& rel_time, Predicate pred);

功能与wait相同,区别在于可以指定一个rel_time相对时间,若等待时间超过该时间或在该时间内收到通知,则线程会被解除阻塞。
对于无条件版本,其返回值是枚举类型cv_status。若因超过指定时间而返回,则返回值为枚举量timeout;对于其他情况,返回值为no_timeout
对于有条件版本,其返回值由谓词pred决定,与pred()返回值一致。

condition_variable::wait_until

//无条件版本
template <class Clock, class Duration>
  cv_status wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time);
//有条件版本
template <class Clock, class Duration, class Predicate>
       bool wait_until (unique_lock<mutex>& lck,
                        const chrono::time_point<Clock,Duration>& abs_time,
                        Predicate pred);                        

功能与wait相同,区别在于可以指定一个abs_time绝对时间,若当前时间达到该绝对时间或在此期间内收到通知信号,则当前线程被解除阻塞。
该函数返回值与wait_for相同。

std::class cv_status

enum class cv_status {no_timeout, timeout};

该类型指示函数是否因超时而返回。

std::notify_all_at_thread_exit

void notify_all_at_thread_exit (condition_variable& cond, unique_lock<mutex> lck);

当调用该函数的线程退出时,会通知所有等待cond的线程重新运行。
该函数也会获得由lck管理的mutex对象的所有权,该mutex对象被存储在函数内部,并在线程退出时解锁(在通知所有线程之前操作)。
形参lck由当前线程上锁,并被该函数获得。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值