reference

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>

Inheritance diagram for ofThread:
ofAppEGLWindow ofURLFileLoaderImpl

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
mutexBlocksSet 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
millisecondsThe 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()

void ofThread::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
callStopThreadSet 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.
millisecondsIf 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.
See also
http://pocoproject.org/slides/090-NotificationsEvents.pdf
http://pocoproject.org/docs/Poco.Condition.html
http://pocoproject.org/docs/Poco.Event.html
http://pocoproject.org/docs/Poco.Semaphore.html

◆ 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

std::mutex ofThread::mutex
mutableprotected

The internal mutex called through lock() & unlock().

This mutext can also be used with std::unique_lock or lock_guard within the threaded function by calling:

std::unique_lock<std::mutex> lock(mutex);

◆ thread

std::thread ofThread::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