condition_variables.qbk

来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 514 行 · 第 1/2 页

QBK
514
字号
[/  (C) Copyright 2007-8 Anthony Williams.  Distributed under the Boost Software License, Version 1.0.  (See accompanying file LICENSE_1_0.txt or copy at  http://www.boost.org/LICENSE_1_0.txt).][section:condvar_ref Condition Variables][heading Synopsis]The classes `condition_variable` and `condition_variable_any` provide amechanism for one thread to wait for notification from another thread that aparticular condition has become true. The general usage pattern is that onethread locks a mutex and then calls `wait` on an instance of`condition_variable` or `condition_variable_any`. When the thread is woken fromthe wait, then it checks to see if the appropriate condition is now true, andcontinues if so. If the condition is not true, then the thread then calls `wait`again to resume waiting. In the simplest case, this condition is just a booleanvariable:    boost::condition_variable cond;    boost::mutex mut;    bool data_ready;    void process_data();    void wait_for_data_to_process()    {        boost::unique_lock<boost::mutex> lock(mut);        while(!data_ready)        {            cond.wait(lock);        }        process_data();    }Notice that the `lock` is passed to `wait`: `wait` will atomically add thethread to the set of threads waiting on the condition variable, and unlock themutex. When the thread is woken, the mutex will be locked again before the callto `wait` returns. This allows other threads to acquire the mutex in order toupdate the shared data, and ensures that the data associated with the conditionis correctly synchronized.In the mean time, another thread sets the condition to `true`, and then callseither `notify_one` or `notify_all` on the condition variable to wake onewaiting thread or all the waiting threads respectively.    void retrieve_data();    void prepare_data();    void prepare_data_for_processing()    {        retrieve_data();        prepare_data();        {            boost::lock_guard<boost::mutex> lock(mut);            data_ready=true;        }        cond.notify_one();    }Note that the same mutex is locked before the shared data is updated, but thatthe mutex does not have to be locked across the call to `notify_one`.This example uses an object of type `condition_variable`, but would work just aswell with an object of type `condition_variable_any`: `condition_variable_any`is more general, and will work with any kind of lock or mutex, whereas`condition_variable` requires that the lock passed to `wait` is an instance of`boost::unique_lock<boost::mutex>`. This enables `condition_variable` to makeoptimizations in some cases, based on the knowledge of the mutex type;`condition_variable_any` typically has a more complex implementation than`condition_variable`.[section:condition_variable Class `condition_variable`]    #include <boost/thread/condition_variable.hpp>    namespace boost    {        class condition_variable        {        public:            condition_variable();            ~condition_variable();            void notify_one();            void notify_all();            void wait(boost::unique_lock<boost::mutex>& lock);            template<typename predicate_type>            void wait(boost::unique_lock<boost::mutex>& lock,predicate_type predicate);            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time);            template<typename duration_type>            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time);            template<typename predicate_type>            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time,predicate_type predicate);            template<typename duration_type,typename predicate_type>            bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time,predicate_type predicate);        // backwards compatibility            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time);            template<typename predicate_type>            bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::xtime const& abs_time,predicate_type predicate);        };    }[section:constructor `condition_variable()`][variablelist[[Effects:] [Constructs an object of class `condition_variable`.]][[Throws:] [__thread_resource_error__ if an error occurs.]]][endsect][section:destructor `~condition_variable()`][variablelist[[Precondition:] [All threads waiting on `*this` have been notified by a call to`notify_one` or `notify_all` (though the respective calls to `wait` or`timed_wait` need not have returned).]][[Effects:] [Destroys the object.]][[Throws:] [Nothing.]]][endsect][section:notify_one `void notify_one()`][variablelist[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a callto `wait` or `timed_wait`, unblocks one of those threads.]][[Throws:] [Nothing.]]][endsect][section:notify_all `void notify_all()`][variablelist[[Effects:] [If any threads are currently __blocked__ waiting on `*this` in a callto `wait` or `timed_wait`, unblocks all of those threads.]][[Throws:] [Nothing.]]][endsect][section:wait `void wait(boost::unique_lock<boost::mutex>& lock)`][variablelist[[Precondition:] [`lock` is locked by the current thread, and either no otherthread is currently waiting on `*this`, or the execution of the `mutex()` memberfunction on the `lock` objects supplied in the calls to `wait` or `timed_wait`in all the threads currently waiting on `*this` would return the same value as`lock->mutex()` for this call to `wait`.]][[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. Thethread will unblock when notified by a call to `this->notify_one()` or`this->notify_all()`, or spuriously. When the thread is unblocked (for whateverreason), the lock is reacquired by invoking `lock.lock()` before the call to`wait` returns. The lock is also reacquired by invoking `lock.lock()` if thefunction exits with an exception.]][[Postcondition:] [`lock` is locked by the current thread.]][[Throws:] [__thread_resource_error__ if an erroroccurs. __thread_interrupted__ if the wait was interrupted by a call to__interrupt__ on the __thread__ object associated with the current thread of execution.]]][endsect][section:wait_predicate `template<typename predicate_type> void wait(boost::unique_lock<boost::mutex>& lock, predicate_type pred)`][variablelist[[Effects:] [As-if ``while(!pred()){    wait(lock);}``]]][endsect][section:timed_wait `bool timed_wait(boost::unique_lock<boost::mutex>& lock,boost::system_time const& abs_time)`][variablelist[[Precondition:] [`lock` is locked by the current thread, and either no otherthread is currently waiting on `*this`, or the execution of the `mutex()` memberfunction on the `lock` objects supplied in the calls to `wait` or `timed_wait`in all the threads currently waiting on `*this` would return the same value as`lock->mutex()` for this call to `wait`.]][[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. Thethread will unblock when notified by a call to `this->notify_one()` or`this->notify_all()`, when the time as reported by `boost::get_system_time()`would be equal to or later than the specified `abs_time`, or spuriously. Whenthe thread is unblocked (for whatever reason), the lock is reacquired byinvoking `lock.lock()` before the call to `wait` returns. The lock is alsoreacquired by invoking `lock.lock()` if the function exits with an exception.]][[Returns:] [`false` if the call is returning because the time specified by`abs_time` was reached, `true` otherwise.]][[Postcondition:] [`lock` is locked by the current thread.]][[Throws:] [__thread_resource_error__ if an erroroccurs. __thread_interrupted__ if the wait was interrupted by a call to__interrupt__ on the __thread__ object associated with the current thread of execution.]]][endsect][section:timed_wait_rel `template<typename duration_type> bool timed_wait(boost::unique_lock<boost::mutex>& lock,duration_type const& rel_time)`][variablelist[[Precondition:] [`lock` is locked by the current thread, and either no otherthread is currently waiting on `*this`, or the execution of the `mutex()` memberfunction on the `lock` objects supplied in the calls to `wait` or `timed_wait`in all the threads currently waiting on `*this` would return the same value as`lock->mutex()` for this call to `wait`.]][[Effects:] [Atomically call `lock.unlock()` and blocks the current thread. Thethread will unblock when notified by a call to `this->notify_one()` or`this->notify_all()`, after the period of time indicated by the `rel_time`argument has elapsed, or spuriously. When the thread is unblocked (for whateverreason), the lock is reacquired by invoking `lock.lock()` before the call to`wait` returns. The lock is also reacquired by invoking `lock.lock()` if the

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?