This documentation is automatically generated from the openFrameworks source code using doxygen and refers to the most recent release, version 0.12.0.
A threaded base class with a built in mutex for convenience. More...
#include <ofThread.h>

Public Types | |
enum | { INFINITE_JOIN_TIMEOUT = -1 } |
Public Member Functions | |
ofThread () | |
Create an ofThread. | |
bool | isThreadRunning () const |
Check the running status of the thread. | |
std::thread::id | getThreadId () const |
Get the unique thread id. | |
std::string | getThreadName () const |
Get the unique thread name, in the form of "Thread id#". | |
void | setThreadName (const std::string &name) |
void | startThread () |
Start the thread. | |
OF_DEPRECATED_MSG ("Use tryLock instead of setting the type of lock on startThread", void startThread(bool mutexBlocks)) | |
Start the thread with options. | |
bool | lock () |
Lock the mutex. | |
bool | tryLock () |
Tries to lock the mutex. | |
void | unlock () |
Unlock the mutex. | |
void | stopThread () |
Stop the thread. | |
void | waitForThread (bool callStopThread=true, long milliseconds=INFINITE_JOIN_TIMEOUT) |
Wait for the thread to exit (aka "joining" the thread). | |
void | sleep (long milliseconds) |
Tell the thread to sleep for a certain amount of milliseconds. | |
void | yield () |
Tell the thread to give up its CPU time other threads. | |
bool | isCurrentThread () const |
Query whether the current thread is active. | |
std::thread & | getNativeThread () |
Get a reference to the underlying Poco thread. | |
const std::thread & | getNativeThread () const |
Get a const reference to the underlying Poco thread. | |
Protected Member Functions | |
virtual void | threadedFunction () |
The thread's run function. | |
Protected Attributes | |
std::thread | thread |
The Poco::Thread that runs the Poco::Runnable. | |
std::mutex | mutex |
The internal mutex called through lock() & unlock(). | |
Detailed Description
A threaded base class with a built in mutex for convenience.
Users can extend this base class by public inheritance like this:
class MyThreadedClass: public ofThread { public: /// ... void threadedFunction() { while(isThreadRunning()) { /// Threaded function here. } } };
ofThread is a convenient wrapper for Poco::Thread, Poco::Runnable and Poco::Mutex. It represents a simplified (sometimes overly simplified - or simplified in ways that might not make sense for your project) pathway for quickly writing threaded classes. Poco::Runnable represents a class that can be "run" via its void run() method. Poco::Thread is able to spawn a thread and "run" the contents of a class that extends the Poco::Runnable interface (which ofThread does). Poco::FastMutex, (aka ofMutex) is a "mutual exclusion" object that prevents two threads from accessing the same data at the same time. It is important to know that Poco::FastMutex (aka ofMutex) is not "recursive" while Poco::Mutex is. This means that if the same thread attempts to lock a thread while it ALREADY has a lock on the mutex, the program will lock up and go nowhere. Thus, it is important that ofThread subclasses carefully their use of the mutex. Currently ofThread does not lock its own mutex at any point (e.g. ofThread's internal variables are not thread safe). This is a somewhat dangerous convenience that is (theoretically) supposed to make it easier for subclasses to avoid the recursive mutex "problem". The situation that arises from two threads simultanously reading or writing from the same shared data (shared data occupies the same physical location in memory) leads to something called a "race condition", which can lead to deadlocks. A deadlock is as bad as it sounds. It means your program just stops. ofMutex prevents race conditions, deadlocks and crashes by permitting only one thread access to shared data at a time. When using mutexes to protect data, the trick is to always be sure to unlock the mutex when finished. This problem can often be avoided by using an Poco::FastMutex::ScopedLock (aka ofScopedLock). See the the documentation for more information. Finally, there are many cases where it might make more sense to use Poco::Thread, Poco::Runnable and Poco::FastMutex directly rather than using ofThread. Further, cross platform thread management will be alleviated with the std::thread support library included with C++11.
Uncaught Exceptions throw from within ofThread will cause the thread to stop and the Exception will be delivered to the default ofBaseThreadErrorHandler. The ofBaseThreadErrorHandler will print the exception details, if available. The ofBaseThreadErrorHandler offers no opportunity to take corrective action and only allows the user to receive more valuable debugging information about the uncaught exception. Users should design ofThread subclasses to catch and respond to all anticipated exceptions.
Member Enumeration Documentation
◆ anonymous enum
anonymous enum |
Enumerator | |
---|---|
INFINITE_JOIN_TIMEOUT | A sentinal value for an infinite join timeout. Primarily used with the waitForThread() method. |
Constructor & Destructor Documentation
◆ ofThread()
ofThread::ofThread | ( | ) |
Create an ofThread.
Member Function Documentation
◆ getNativeThread() [1/2]
std::thread & ofThread::getNativeThread | ( | ) |
Get a reference to the underlying Poco thread.
Poco::Thread provides a clean cross-platform wrapper for threads. On occasion, it may be useful to interact with the underlying Poco::Thread directly.
- Returns
- A reference to the backing Poco thread.
◆ getNativeThread() [2/2]
const std::thread & ofThread::getNativeThread | ( | ) | const |
Get a const reference to the underlying Poco thread.
Poco::Thread provides a clean cross-platform wrapper for threads. On occasion, it may be useful to interact with the underlying Poco::Thread directly.
- Returns
- A reference to the backing Poco thread.
◆ getThreadId()
std::thread::id ofThread::getThreadId | ( | ) | const |
Get the unique thread id.
- Note
- This is NOT the the same as the operating thread id!
◆ getThreadName()
std::string ofThread::getThreadName | ( | ) | const |
Get the unique thread name, in the form of "Thread id#".
- Returns
- the Thread ID string.
◆ isCurrentThread()
bool ofThread::isCurrentThread | ( | ) | const |
Query whether the current thread is active.
In multithreaded situations, it can be useful to know which thread is currently running some code in order to make sure only certain threads can do certain things. For example, OpenGL can only run in the main execution thread. Thus, situations where a thread is responsible for interacting with graphics resources may need to prevent graphics updates unless the main thread is accessing or updating resources shared with this ofThread (or its subclass).
if(myThread.isCurrentThread()) { // do some myThread things, // but keep your hands off my resources! } else if(ofThread::isMainThread()) { // pheew! ok, update those graphics resources }
By way of another example, a subclass of ofThread may have an update() method that is called from ofBaseApp during the execution of the main application thread. In these cases, the ofThread subclass might want to ask itself whether it can, for instance, call update() on an ofImage, in order to send copy some ofPixels to an ofTexture on the graphics card.
- Returns
- True iff this ofThread the currently active thread.
◆ isThreadRunning()
bool ofThread::isThreadRunning | ( | ) | const |
Check the running status of the thread.
- Returns
- true iff the thread is currently running.
◆ lock()
bool ofThread::lock | ( | ) |
Lock the mutex.
If the thread was started startThread(true), then this call will wait until the mutex is available and return true. If the thread was started startThread(false), this call will return true iff the mutex is was successfully acquired.
- Returns
- true if the lock was successfully acquired.
◆ OF_DEPRECATED_MSG()
ofThread::OF_DEPRECATED_MSG | ( | "Use tryLock instead of setting the type of lock on startThread" | , |
void | startThreadbool mutexBlocks | ||
) |
Start the thread with options.
- Parameters
-
mutexBlocks Set blocking to true if you want the mutex to block when lock() is called.
- Note
- Subclasses can directly access the mutex and employ thier own locking strategy.
◆ setThreadName()
void ofThread::setThreadName | ( | const std::string & | name | ) |
◆ sleep()
void ofThread::sleep | ( | long | milliseconds | ) |
Tell the thread to sleep for a certain amount of milliseconds.
This is useful inside the threadedFunction() when a thread is waiting for input to process:
void MyThreadedClass::threadedFunction() { // start while(isThreadRunning()) { // bReadyToProcess can be set from outside the threadedFuntion. // perhaps by another thread that downloads data, or loads // some media, etc. if(bReadyToProcess == true) { // do some time intensive processing bReadyToProcess = false; } else { // sleep the thread to give up some cpu sleep(20); } } // done }
If the user does not give the thread a chance to sleep, the thread may take 100% of the CPU core while it's looping as it waits for something to do. This may lead to poor application performance.
- Parameters
-
milliseconds The number of milliseconds to sleep.
◆ startThread()
void ofThread::startThread | ( | ) |
Start the thread.
- Note
- Subclasses can directly access the mutex and employ thier own locking strategy.
◆ stopThread()
void ofThread::stopThread | ( | ) |
Stop the thread.
This does immediately stop the thread from processing, but will only set a flag that must be checked from within your threadedFunction() by calling isThreadRunning(). If the user wants to both stop the thread AND wait for the thread to finish processing, the user should call waitForThread(true, ...).
◆ threadedFunction()
|
protectedvirtual |
The thread's run function.
Users must overide this in your their derived class and then implement their threaded activity inside the loop. If the the users's threadedFunction does not have a loop, the contents of the threadedFunction will be executed once and the thread will then exit.
For tasks that must be repeated, the user can use a while loop that will run repeatedly until the thread's threadRunning is set to false via the stopThread() method.
void MyThreadedClass::threadedFunction() { // Start the loop and continue until // isThreadRunning() returns false. while(isThreadRunning()) { // Do activity repeatedly here: // int j = 1 + 1; // This while loop will run as fast as it possibly // can, consuming as much processor speed as it can. // To help the processor stay cool, users are // encouraged to let the while loop sleep via the // sleep() method, or call the yield() method to let // other threads have a turn. See the sleep() and // yield() methods for more information. // sleep(100); } }
Reimplemented in ofAppEGLWindow, and ofURLFileLoaderImpl.
◆ tryLock()
bool ofThread::tryLock | ( | ) |
Tries to lock the mutex.
If the thread was started startThread(true), then this call will wait until the mutex is available and return true. If the thread was started startThread(false), this call will return true iff the mutex is was successfully acquired.
- Returns
- true if the lock was successfully acquired.
◆ unlock()
void ofThread::unlock | ( | ) |
Unlock the mutex.
This will only unlocks the mutex if it was previously by the same calling thread.
◆ waitForThread()
void ofThread::waitForThread | ( | bool | callStopThread = true , |
long | milliseconds = INFINITE_JOIN_TIMEOUT |
||
) |
Wait for the thread to exit (aka "joining" the thread).
This method waits for a thread will "block" and wait for the thread (aka "join" the thread) before it returns. This allows the user to be sure that the thread is properly cleaned up. An example of when this might be particularly important is if the threadedFunction() is opening a set of network sockets, or downloading data from the web. Destroying an ofThread subclass without releasing those sockets (or other resources), may result in segmentation faults, error signals or other undefined behaviors.
- Parameters
-
callStopThread Set stop to true if you want to signal the thread to exit before waiting. This is the equivalent to calling stopThread(). If you your threadedFunction uses a while-loop that depends on isThreadRunning() and you do not call stopThread() or set stop == true, waitForThread will hang indefinitely. Set stop == false ONLY if you have already called stopThread() and you simply need to be sure your thread has finished its tasks. milliseconds If millseconds is set to INFINITE_JOIN_TIMEOUT, the waitForThread will wait indefinitely for the thread to complete. If milliseconds is set to a lower number (e.g. 10000 for 10 seconds), waitForThread will wait for 10000 milliseconds and if the thread has not yet stopped it will return and log an error message. Users are encouraged to use the default INFINITE_JOIN_TIMEOUT. If the user is unhappy with the amount of time it takes to join a thread, the user is encouraged to seek more expedient ways of signalling their desire for a thread to complete via other signalling methods such as Poco::Event, Poco::Condition, or Poco::Semaphore.
◆ yield()
void ofThread::yield | ( | ) |
Tell the thread to give up its CPU time other threads.
This method is similar to sleep() and can often be used in the same way. The main difference is that 1 millisecond (the minimum sleep time available with sleep()) is a very long time on modern processors and yield() simply gives up processing time to the next thread, instead of waiting for number of milliseconds. In some cases, this behavior will be preferred.
Member Data Documentation
◆ mutex
|
mutableprotected |
◆ thread
|
protected |
The Poco::Thread that runs the Poco::Runnable.
The documentation for this class was generated from the following files:
- /Users/icq4ever/Desktop/oF0120/libs/openFrameworks/utils/ofThread.h
- /Users/icq4ever/Desktop/oF0120/libs/openFrameworks/utils/ofThread.cpp