|
OpenTop 1.3 | |||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | Cross-Platform C++ | ||||
SUMMARY: CONSTRUCTOR | METHOD | DETAIL: CONSTRUCTOR | METHOD |
#include "ot/base/ConditionVariable.h"
Provides a means for a thread to be signalled when a condition becomes true.
When a thread has acquired a mutex on some shared data, but then finds that the data is not in the correct state for it to do some work, then it should release the mutex and wait for another thread to signal it that the shared data has changed. This is the basic function of a POSIX-style condition variable.A condition variable is always used in conjunction with a mutex. The mutex is used to synchronize access to the shared data, and the condition variable is used to signal to waiting threads that a condition or predicate has become true.
A program cannot examine the shared data without having the mutex locked. But if the mutex is locked, no other thread will be able to change the state, so the wait operation atomically releases the mutex and blocks the thread pending a signal from another thread. When the waiting thread is signalled, the mutex is re-acquired before the wait() method returns to the caller.
Here is a simple example of a thread that pulls a single item from a queue. If the queue is empty, it blocks until an item becomes available:
WorkItem Worker::getNextWorkItem() { // acquire the queue's mutex RecursiveMutex::Lock lock(m_queueMutex); while(m_queue.empty()) { try { // mutex is released for the wait... m_queueCV.wait(); // ...and re-acquired on return } catch(InterruptedException& e) {} } // pop the first item from the work queue WorkItem ret = m_queue.front(); m_queue.pop_front(); return ret; // mutex lock is automatically released on exit }
Note the structure of this function, where the predicate is tested in a while loop. This is a standard and recommended technique which is used to make the function robust in the presence of spurious wake-ups.
Following on from the previous example, here is a function that adds an item to the queue and signals the waiting thread that there is some work to be done:
void Worker::queueWorkItem(const WorkItem& item) { // acquire the queue's mutex RecursiveMutex::Lock lock(m_queueMutex); m_queue.push_back(item); // inform a waiting thread that a work item is now available m_queueCV.signal(); // mutex is automatically released on exit from the scope }
In the above example it is not a requirement that the mutex lock be held while the signal() operation is performed, but it is generally better to do so. If the function added multiple items to the queue, then broadcast() would be a better choice than signal() if multiple worker threads could be waiting on the queue.
A single condition variable may be associated with more than one mutex. Likewise a single mutex may be associated with more than one condition variable.
On POSIX-compliant systems this class is a simple wrapper around a POSIX threads condition variable. On other systems, a condition variable is emulated using the available synchronization primitives.
Constructor/Destructor Summary | |
ConditionVariable() Constructs a ConditionVariable. | |
~ConditionVariable() Releases system resources associated with this ConditionVariable. |
Method Summary | |
void |
broadcast() Awakens all threads that are waiting on this condition variable. |
void |
signal() Awakens one of the threads that are waiting on this condition variable. |
void |
wait(RecursiveMutex& mutex) Waits and blocks the calling thread until the ConditionVariable becomes signalled. |
bool |
wait(RecursiveMutex& mutex, unsigned long milliseconds) Waits and blocks the calling thread until the ConditionVariable becomes signalled or the timeout value expires. |
Constructor/Destructor Detail |
ConditionVariable()
~ConditionVariable()
Method Detail |
void broadcast()
void signal()
When a thread is awakened, it re-acquires the mutex that was released by the wait() call before returning to the application.
void wait(RecursiveMutex& mutex)
Upon completion, the mutex is locked and owned by the calling thread.
On most occasions, control is not returned to the caller until another thread has called signal() or broadcast() on this ConditionVariable. However, it is possible for spurious wake-ups to occur. For this reason, the caller should always check the condition in a while loop.
mutex
- bool wait(RecursiveMutex& mutex, unsigned long milliseconds)
Upon completion, the mutex is locked and owned by the calling thread.
mutex
- milliseconds
- InterruptedException
-
|
OpenTop 1.3 | |||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | Cross-Platform C++ | ||||
SUMMARY: CONSTRUCTOR | METHOD | DETAIL: CONSTRUCTOR | METHOD |