• D.2 <condition_variable>头文件
    • 头文件内容
  • D.2.1 std::condition_variable类
    • 类型定义
    • std::condition_variable 默认构造函数
    • std::condition_variable 析构函数
    • std::condition_variable::notify_one 成员函数
    • std::condition_variable::notify_all 成员函数
    • std::condition_variable::wait 成员函数
    • std::condition_variable::wait 需要一个谓词的成员函数重载
    • std::condition_variable::wait_for 成员函数
    • std::condition_variable::wait_for 需要一个谓词的成员函数重载
    • std::condition_variable::wait_until 成员函数
    • std::condition_variable::wait_until 需要一个谓词的成员函数重载
    • std::notify_all_at_thread_exit 非成员函数
  • D.2.2 std::condition_variable_any类
    • 类型定义
    • std::condition_variable_any 默认构造函数
    • std::condition_variable_any 析构函数
    • std::condition_variable_any::notify_one 成员函数
    • std::condition_variable_any::notify_all 成员函数
    • std::condition_variable_any::wait 成员函数
    • std::condition_variable_any::wait 需要一个谓词的成员函数重载
    • std::condition_variable_any::wait_for 成员函数
    • std::condition_variable_any::wait_for 需要一个谓词的成员函数重载
    • std::condition_variable_any::wait_until 成员函数
    • std::condition_variable_any::wait_unti 需要一个谓词的成员函数重载

    D.2 <condition_variable>头文件

    <condition_variable>头文件提供了条件变量的定义。其作为基本同步机制,允许被阻塞的线程在某些条件达成或超时时,解除阻塞继续执行。

    头文件内容

    1. namespace std
    2. {
    3. enum class cv_status { timeout, no_timeout };
    4. class condition_variable;
    5. class condition_variable_any;
    6. }

    D.2.1 std::condition_variable类

    std::condition_variable允许阻塞一个线程,直到条件达成。

    std::condition_variable实例不支持CopyAssignable(拷贝赋值), CopyConstructible(拷贝构造), MoveAssignable(移动赋值)和 MoveConstructible(移动构造)。

    类型定义

    1. class condition_variable
    2. {
    3. public:
    4. condition_variable();
    5. ~condition_variable();
    6. condition_variable(condition_variable const& ) = delete;
    7. condition_variable& operator=(condition_variable const& ) = delete;
    8. void notify_one() noexcept;
    9. void notify_all() noexcept;
    10. void wait(std::unique_lock<std::mutex>& lock);
    11. template <typename Predicate>
    12. void wait(std::unique_lock<std::mutex>& lock,Predicate pred);
    13. template <typename Clock, typename Duration>
    14. cv_status wait_until(
    15. std::unique_lock<std::mutex>& lock,
    16. const std::chrono::time_point<Clock, Duration>& absolute_time);
    17. template <typename Clock, typename Duration, typename Predicate>
    18. bool wait_until(
    19. std::unique_lock<std::mutex>& lock,
    20. const std::chrono::time_point<Clock, Duration>& absolute_time,
    21. Predicate pred);
    22. template <typename Rep, typename Period>
    23. cv_status wait_for(
    24. std::unique_lock<std::mutex>& lock,
    25. const std::chrono::duration<Rep, Period>& relative_time);
    26. template <typename Rep, typename Period, typename Predicate>
    27. bool wait_for(
    28. std::unique_lock<std::mutex>& lock,
    29. const std::chrono::duration<Rep, Period>& relative_time,
    30. Predicate pred);
    31. };
    32. void notify_all_at_thread_exit(condition_variable&,unique_lock<mutex>);

    std::condition_variable 默认构造函数

    构造一个std::condition_variable对象。

    声明

    1. condition_variable();

    效果

    构造一个新的std::condition_variable实例。

    抛出

    当条件变量无法够早的时候,将会抛出一个std::system_error异常。

    std::condition_variable 析构函数

    销毁一个std::condition_variable对象。

    声明

    1. ~condition_variable();

    先决条件

    之前没有使用*this总的wait(),wait_for()或wait_until()阻塞过线程。

    效果

    销毁*this。

    抛出

    std::condition_variable::notify_one 成员函数

    唤醒一个等待当前std::condition_variable实例的线程。

    声明

    1. void notify_one() noexcept;

    效果

    唤醒一个等待*this的线程。如果没有线程在等待,那么调用没有任何效果。

    抛出

    当效果没有达成,就会抛出std::system_error异常。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::notify_all 成员函数

    唤醒所有等待当前std::condition_variable实例的线程。

    声明

    1. void notify_all() noexcept;

    效果

    唤醒所有等待*this的线程。如果没有线程在等待,那么调用没有任何效果。

    抛出

    当效果没有达成,就会抛出std::system_error异常

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait 成员函数

    通过std::condition_variable的notify_one()、notify_all()或伪唤醒结束等待。

    等待

    1. void wait(std::unique_lock<std::mutex>& lock);

    先决条件

    当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    自动解锁lock对象,对于线程等待线程,当其他线程调用notify_one()或notify_all()时被唤醒,亦或该线程处于伪唤醒状态。在wait()返回前,lock对象将会再次上锁。

    抛出

    当效果没有达成的时候,将会抛出std::system_error异常。当lock对象在调用wait()阶段被解锁,那么当wait()退出的时候lock会再次上锁,即使函数是通过异常的方式退出。

    NOTE:伪唤醒意味着一个线程调用wait()后,在没有其他线程调用notify_one()或notify_all()时,还处以苏醒状态。因此,建议对wait()进行重载,在可能的情况下使用一个谓词。否则,建议wait()使用循环检查与条件变量相关的谓词。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait 需要一个谓词的成员函数重载

    等待std::condition_variable上的notify_one()或notify_all()被调用,或谓词为true的情况,来唤醒线程。

    声明

    1. template<typename Predicate>
    2. void wait(std::unique_lock<std::mutex>& lock,Predicate pred);

    先决条件

    pred()谓词必须是合法的,并且需要返回一个值,这个值可以和bool互相转化。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    正如

    1. while(!pred())
    2. {
    3. wait(lock);
    4. }

    抛出

    pred中可以抛出任意异常,或者当效果没有达到的时候,抛出std::system_error异常。

    NOTE:潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后,返回true。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait_for 成员函数

    std::condition_variable在调用notify_one()、调用notify_all()、超时或线程伪唤醒时,结束等待。

    声明

    1. template<typename Rep,typename Period>
    2. cv_status wait_for(
    3. std::unique_lock<std::mutex>& lock,
    4. std::chrono::duration<Rep,Period> const& relative_time);

    先决条件

    当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    当其他线程调用notify_one()或notify_all()函数时,或超出了relative_time的时间,亦或是线程被伪唤醒,则将lock对象自动解锁,并将阻塞线程唤醒。当wait_for()调用返回前,lock对象会再次上锁。

    返回

    线程被notify_one()、notify_all()或伪唤醒唤醒时,会返回std::cv_status::no_timeout;反之,则返回std::cv_status::timeout

    抛出

    当效果没有达成的时候,会抛出std::system_error异常。当lock对象在调用wait_for()函数前解锁,那么lock对象会在wait_for()退出前再次上锁,即使函数是以异常的方式退出。

    NOTE:伪唤醒意味着,一个线程在调用wait_for()的时候,即使没有其他线程调用notify_one()和notify_all()函数,也处于苏醒状态。因此,这里建议重载wait_for()函数,重载函数可以使用谓词。要不,则建议wait_for()使用循环的方式对与谓词相关的条件变量进行检查。在这样做的时候还需要小心,以确保超时部分依旧有效;wait_until()可能适合更多的情况。这样的话,线程阻塞的时间就要比指定的时间长了。在有这样可能性的地方,流逝的时间是由稳定时钟决定。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait_for 需要一个谓词的成员函数重载

    std::condition_variable在调用notify_one()、调用notify_all()、超时或线程伪唤醒时,结束等待。

    声明

    1. template<typename Rep,typename Period,typename Predicate>
    2. bool wait_for(
    3. std::unique_lock<std::mutex>& lock,
    4. std::chrono::duration<Rep,Period> const& relative_time,
    5. Predicate pred);

    先决条件

    pred()谓词必须是合法的,并且需要返回一个值,这个值可以和bool互相转化。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    等价于

    1. internal_clock::time_point end=internal_clock::now()+relative_time;
    2. while(!pred())
    3. {
    4. std::chrono::duration<Rep,Period> remaining_time=
    5. end-internal_clock::now();
    6. if(wait_for(lock,remaining_time)==std::cv_status::timeout)
    7. return pred();
    8. }
    9. return true;

    返回

    当pred()为true,则返回true;当超过relative_time并且pred()返回false时,返回false。

    NOTE:潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后返回true,或在指定时间relative_time内完成。线程阻塞的时间就要比指定的时间长了。在有这样可能性的地方,流逝的时间是由稳定时钟决定。

    抛出

    当效果没有达成时,会抛出std::system_error异常或者由pred抛出任意异常。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait_until 成员函数

    std::condition_variable在调用notify_one()、调用notify_all()、指定时间内达成条件或线程伪唤醒时,结束等待。

    声明

    1. template<typename Clock,typename Duration>
    2. cv_status wait_until(
    3. std::unique_lock<std::mutex>& lock,
    4. std::chrono::time_point<Clock,Duration> const& absolute_time);

    先决条件

    当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    当其他线程调用notify_one()或notify_all()函数,或Clock::now()返回一个大于或等于absolute_time的时间,亦或线程伪唤醒,lock都将自动解锁,并且唤醒阻塞的线程。在wait_until()返回之前lock对象会再次上锁。

    返回

    线程被notify_one()、notify_all()或伪唤醒唤醒时,会返回std::cv_status::no_timeout;反之,则返回std::cv_status::timeout

    抛出

    当效果没有达成的时候,会抛出std::system_error异常。当lock对象在调用wait_for()函数前解锁,那么lock对象会在wait_for()退出前再次上锁,即使函数是以异常的方式退出。

    NOTE:伪唤醒意味着一个线程调用wait()后,在没有其他线程调用notify_one()或notify_all()时,还处以苏醒状态。因此,这里建议重载wait_until()函数,重载函数可以使用谓词。要不,则建议wait_until()使用循环的方式对与谓词相关的条件变量进行检查。这里不保证线程会被阻塞多长时间,只有当函数返回false后(Clock::now()的返回值大于或等于absolute_time),线程才能解除阻塞。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable::wait_until 需要一个谓词的成员函数重载

    std::condition_variable在调用notify_one()、调用notify_all()、谓词返回true或指定时间内达到条件,结束等待。

    声明

    1. template<typename Clock,typename Duration,typename Predicate>
    2. bool wait_until(
    3. std::unique_lock<std::mutex>& lock,
    4. std::chrono::time_point<Clock,Duration> const& absolute_time,
    5. Predicate pred);

    先决条件

    pred()必须是合法的,并且其返回值能转换为bool值。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    等价于

    1. while(!pred())
    2. {
    3. if(wait_until(lock,absolute_time)==std::cv_status::timeout)
    4. return pred();
    5. }
    6. return true;

    返回

    当调用pred()返回true时,返回true;当Clock::now()的时间大于或等于指定的时间absolute_time,并且pred()返回false时,返回false。

    NOTE:潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后返回true,或Clock::now()返回的时间大于或等于absolute_time。这里不保证调用线程将被阻塞的时长,只有当函数返回false后(Clock::now()返回一个等于或大于absolute_time的值),线程接触阻塞。

    抛出

    当效果没有达成时,会抛出std::system_error异常或者由pred抛出任意异常。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::notify_all_at_thread_exit 非成员函数

    当当前调用函数的线程退出时,等待std::condition_variable的所有线程将会被唤醒。

    声明

    1. void notify_all_at_thread_exit(
    2. condition_variable& cv,unique_lock<mutex> lk);

    先决条件

    当线程调用wait()即可获得锁的所有权,lk.owns_lock()必须为true。lk.mutex()需要返回的值要与并发等待线程相关的任意cv中锁对象提供的wait(),wait_for()或wait_until()相同。

    效果

    将lk的所有权转移到内部存储中,并且当有线程退出时,安排被提醒的cv类。这里的提醒等价于

    1. lk.unlock();
    2. cv.notify_all();

    抛出

    当效果没有达成时,抛出std::system_error异常。

    NOTE:在线程退出前,掌握着锁的所有权,所以这里要避免死锁发生。这里建议调用该函数的线程应该尽快退出,并且在该线程可以执行一些阻塞的操作。用户必须保证等地线程不会错误的将唤醒线程当做已退出的线程,特别是伪唤醒。可以通过等待线程上的谓词测试来实现这一功能,在互斥量保护的情况下,只有谓词返回true时线程才能被唤醒,并且在调用notify_all_at_thread_exit(std::condition_variable_any类中函数)前是不会释放锁。

    D.2.2 std::condition_variable_any类

    std::condition_variable_any类允许线程等待某一条件为true的时候继续运行。不过std::condition_variable只能和std::unique_lock<std::mutex>一起使用,std::condition_variable_any可以和任意可上锁(Lockable)类型一起使用。

    std::condition_variable_any实例不能进行拷贝赋值(CopyAssignable)、拷贝构造(CopyConstructible)、移动赋值(MoveAssignable)或移动构造(MoveConstructible)。

    类型定义

    1. class condition_variable_any
    2. {
    3. public:
    4. condition_variable_any();
    5. ~condition_variable_any();
    6. condition_variable_any(
    7. condition_variable_any const& ) = delete;
    8. condition_variable_any& operator=(
    9. condition_variable_any const& ) = delete;
    10. void notify_one() noexcept;
    11. void notify_all() noexcept;
    12. template<typename Lockable>
    13. void wait(Lockable& lock);
    14. template <typename Lockable, typename Predicate>
    15. void wait(Lockable& lock, Predicate pred);
    16. template <typename Lockable, typename Clock,typename Duration>
    17. std::cv_status wait_until(
    18. Lockable& lock,
    19. const std::chrono::time_point<Clock, Duration>& absolute_time);
    20. template <
    21. typename Lockable, typename Clock,
    22. typename Duration, typename Predicate>
    23. bool wait_until(
    24. Lockable& lock,
    25. const std::chrono::time_point<Clock, Duration>& absolute_time,
    26. Predicate pred);
    27. template <typename Lockable, typename Rep, typename Period>
    28. std::cv_status wait_for(
    29. Lockable& lock,
    30. const std::chrono::duration<Rep, Period>& relative_time);
    31. template <
    32. typename Lockable, typename Rep,
    33. typename Period, typename Predicate>
    34. bool wait_for(
    35. Lockable& lock,
    36. const std::chrono::duration<Rep, Period>& relative_time,
    37. Predicate pred);
    38. };

    std::condition_variable_any 默认构造函数

    构造一个std::condition_variable_any对象。

    声明

    1. condition_variable_any();

    效果

    构造一个新的std::condition_variable_any实例。

    抛出

    当条件变量构造成功,将抛出std::system_error异常。

    std::condition_variable_any 析构函数

    销毁std::condition_variable_any对象。

    声明

    1. ~condition_variable_any();

    先决条件

    之前没有使用*this总的wait(),wait_for()或wait_until()阻塞过线程。

    效果

    销毁*this。

    抛出

    std::condition_variable_any::notify_one 成员函数

    std::condition_variable_any唤醒一个等待该条件变量的线程。

    声明

    1. void notify_all() noexcept;

    效果

    唤醒一个等待*this的线程。如果没有线程在等待,那么调用没有任何效果

    抛出

    当效果没有达成,就会抛出std::system_error异常。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::notify_all 成员函数

    唤醒所有等待当前std::condition_variable_any实例的线程。

    声明

    1. void notify_all() noexcept;

    效果

    唤醒所有等待*this的线程。如果没有线程在等待,那么调用没有任何效果

    抛出

    当效果没有达成,就会抛出std::system_error异常。

    同步

    std::condition_variable实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait 成员函数

    通过std::condition_variable_any的notify_one()、notify_all()或伪唤醒结束等待。

    声明

    1. template<typename Lockable>
    2. void wait(Lockable& lock);

    先决条件

    Lockable类型需要能够上锁,lock对象拥有一个锁。

    效果

    自动解锁lock对象,对于线程等待线程,当其他线程调用notify_one()或notify_all()时被唤醒,亦或该线程处于伪唤醒状态。在wait()返回前,lock对象将会再次上锁。

    抛出

    当效果没有达成的时候,将会抛出std::system_error异常。当lock对象在调用wait()阶段被解锁,那么当wait()退出的时候lock会再次上锁,即使函数是通过异常的方式退出。

    NOTE:伪唤醒意味着一个线程调用wait()后,在没有其他线程调用notify_one()或notify_all()时,还处以苏醒状态。因此,建议对wait()进行重载,在可能的情况下使用一个谓词。否则,建议wait()使用循环检查与条件变量相关的谓词。

    同步

    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait 需要一个谓词的成员函数重载

    等待std::condition_variable_any上的notify_one()或notify_all()被调用,或谓词为true的情况,来唤醒线程。

    声明

    1. template<typename Lockable,typename Predicate>
    2. void wait(Lockable& lock,Predicate pred);

    先决条件

    pred()谓词必须是合法的,并且需要返回一个值,这个值可以和bool互相转化。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    正如

    1. while(!pred())
    2. {
    3. wait(lock);
    4. }

    抛出

    pred中可以抛出任意异常,或者当效果没有达到的时候,抛出std::system_error异常。

    NOTE:潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后,返回true。

    同步

    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait_for 成员函数

    std::condition_variable_any在调用notify_one()、调用notify_all()、超时或线程伪唤醒时,结束等待。

    声明

    1. template<typename Lockable,typename Rep,typename Period>
    2. std::cv_status wait_for(
    3. Lockable& lock,
    4. std::chrono::duration<Rep,Period> const& relative_time);

    先决条件

    当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    当其他线程调用notify_one()或notify_all()函数时,或超出了relative_time的时间,亦或是线程被伪唤醒,则将lock对象自动解锁,并将阻塞线程唤醒。当wait_for()调用返回前,lock对象会再次上锁。

    返回

    线程被notify_one()、notify_all()或伪唤醒唤醒时,会返回std::cv_status::no_timeout;反之,则返回std::cv_status::timeout。

    抛出

    当效果没有达成的时候,会抛出std::system_error异常。当lock对象在调用wait_for()函数前解锁,那么lock对象会在wait_for()退出前再次上锁,即使函数是以异常的方式退出。

    NOTE:伪唤醒意味着,一个线程在调用wait_for()的时候,即使没有其他线程调用notify_one()和notify_all()函数,也处于苏醒状态。因此,这里建议重载wait_for()函数,重载函数可以使用谓词。要不,则建议wait_for()使用循环的方式对与谓词相关的条件变量进行检查。在这样做的时候还需要小心,以确保超时部分依旧有效;wait_until()可能适合更多的情况。这样的话,线程阻塞的时间就要比指定的时间长了。在有这样可能性的地方,流逝的时间是由稳定时钟决定。

    同步

    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait_for 需要一个谓词的成员函数重载

    std::condition_variable_any在调用notify_one()、调用notify_all()、超时或线程伪唤醒时,结束等待。

    声明

    1. template<typename Lockable,typename Rep,
    2. typename Period, typename Predicate>
    3. bool wait_for(
    4. Lockable& lock,
    5. std::chrono::duration<Rep,Period> const& relative_time,
    6. Predicate pred);

    先决条件

    pred()谓词必须是合法的,并且需要返回一个值,这个值可以和bool互相转化。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    正如

    1. internal_clock::time_point end=internal_clock::now()+relative_time;
    2. while(!pred())
    3. {
    4. std::chrono::duration<Rep,Period> remaining_time=
    5. end-internal_clock::now();
    6. if(wait_for(lock,remaining_time)==std::cv_status::timeout)
    7. return pred();
    8. }
    9. return true;

    返回

    当pred()为true,则返回true;当超过relative_time并且pred()返回false时,返回false。

    NOTE:
    潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后返回true,或在指定时间relative_time内完成。线程阻塞的时间就要比指定的时间长了。在有这样可能性的地方,流逝的时间是由稳定时钟决定。

    抛出

    当效果没有达成时,会抛出std::system_error异常或者由pred抛出任意异常。

    同步

    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait_until 成员函数

    std::condition_variable_any在调用notify_one()、调用notify_all()、指定时间内达成条件或线程伪唤醒时,结束等待

    声明

    1. template<typename Lockable,typename Clock,typename Duration>
    2. std::cv_status wait_until(
    3. Lockable& lock,
    4. std::chrono::time_point<Clock,Duration> const& absolute_time);

    先决条件

    Lockable类型需要能够上锁,lock对象拥有一个锁。

    效果

    当其他线程调用notify_one()或notify_all()函数,或Clock::now()返回一个大于或等于absolute_time的时间,亦或线程伪唤醒,lock都将自动解锁,并且唤醒阻塞的线程。在wait_until()返回之前lock对象会再次上锁。

    返回

    线程被notify_one()、notify_all()或伪唤醒唤醒时,会返回std::cv_status::no_timeout;反之,则返回std::cv_status::timeout

    抛出

    当效果没有达成的时候,会抛出std::system_error异常。当lock对象在调用wait_for()函数前解锁,那么lock对象会在wait_for()退出前再次上锁,即使函数是以异常的方式退出。

    NOTE:伪唤醒意味着一个线程调用wait()后,在没有其他线程调用notify_one()或notify_all()时,还处以苏醒状态。因此,这里建议重载wait_until()函数,重载函数可以使用谓词。要不,则建议wait_until()使用循环的方式对与谓词相关的条件变量进行检查。这里不保证线程会被阻塞多长时间,只有当函数返回false后(Clock::now()的返回值大于或等于absolute_time),线程才能解除阻塞。

    同步
    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。

    std::condition_variable_any::wait_unti 需要一个谓词的成员函数重载

    std::condition_variable_any在调用notify_one()、调用notify_all()、谓词返回true或指定时间内达到条件,结束等待。

    声明

    1. template<typename Lockable,typename Clock,
    2. typename Duration, typename Predicate>
    3. bool wait_until(
    4. Lockable& lock,
    5. std::chrono::time_point<Clock,Duration> const& absolute_time,
    6. Predicate pred);

    先决条件

    pred()必须是合法的,并且其返回值能转换为bool值。当线程调用wait()即可获得锁的所有权,lock.owns_lock()必须为true。

    效果

    等价于

    1. while(!pred())
    2. {
    3. if(wait_until(lock,absolute_time)==std::cv_status::timeout)
    4. return pred();
    5. }
    6. return true;

    返回

    当调用pred()返回true时,返回true;当Clock::now()的时间大于或等于指定的时间absolute_time,并且pred()返回false时,返回false。

    NOTE:潜在的伪唤醒意味着不会指定pred调用的次数。通过lock进行上锁,pred经常会被互斥量引用所调用,并且函数必须返回(只能返回)一个值,在(bool)pred()评估后返回true,或Clock::now()返回的时间大于或等于absolute_time。这里不保证调用线程将被阻塞的时长,只有当函数返回false后(Clock::now()返回一个等于或大于absolute_time的值),线程接触阻塞。

    抛出

    当效果没有达成时,会抛出std::system_error异常或者由pred抛出任意异常。

    同步

    std::condition_variable_any实例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函数(串行调用)。调用notify_one()或notify_all()只能唤醒正在等待中的线程。