The following classes in ClanLib are related to threads:
clan::Thread is the class representing a handle to a thread. It exports functions to start threads, wait on threads and so on. To start a thread, call the clan::Thread::start function. The start function exist in several different versions, which allow you to specify how to execute the thread main function in a way most convenient for your appliation.
One way is to use a method very common in other languages or libraries, such as Java. The application derives from the class clan::Runnable and implements the clan::Runnable::run function. A pointer to this class is then given to clan::Thread::start:
Although this method is simple and easy to understand, it also forces you to constantly derive a class each time you need to start a thread. Some of the other clan::Thread::start functions allows you to specify a function directly to clan::Thread::start:
The function is not limited to be a static function and just like the ClanLib template callback classes, you can specify a member function and one or more user-data parameters to be passed along:
To wait on a thread to complete its execution, call clan::Thread::join. If you do not call this function, the destructor of clan::Thread will not wait for your thread to complete - it will simply just close its handle to the thread. This means your thread will continue to run, but you will be unable to interact further with it.
Classes in ClanLib are re-entrant (also known as the apartment model), unless otherwise specified. This means that a single class instance can only be safely accessed from one thread at a time (but multiple threads can access different class instances at the same time). To ensure only one thread accesses data or functions simultanously, ClanLib provides the clan::Mutex class. A mutex is an object that can be locked by only one thread at the same time. If any other thread tries to lock the mutex, it will block until the first thread releases its lock.
It is vital to a program's execution that a mutex lock is always freed - otherwise you would eventually get a deadlock of all threads working with the data guarded by the mutex. If an exception was thrown in the above thread main functions, the mutex would not get unlocked. This can be solved by inserting a try / catch clause, or it could be changed to use clan::MutexSection to lock the mutex instead. clan::MutexSection locks a mutex in its constructor and releases it in its destructor, which ensures that all exit paths of a function will eventually unlock a mutex: