#include <Thread.h>
Inheritance diagram for Thread:
Public Methods | |
Thread () | |
virtual | ~Thread () throw () |
Destroy a Thread. | |
bool | operator== (const Thread &t) const |
Comparison operator. | |
bool | operator!= (const Thread &t) const |
Comparison operator. | |
bool | operator== (const Reference &r) const |
Comparison operator. | |
bool | operator!= (const Reference &r) const |
Comparison operator. | |
bool | join (unsigned long timeout=0) |
virtual void | run () throw () |
void | run (const RunnableHandle &task) |
void | run (Runnable *task) |
void | start () |
void | setPriority (Priority p) throw () |
Priority | getPriority () throw () |
virtual bool | interrupt () throw () |
virtual bool | isCanceled () |
virtual void | cancel () |
bool | isDaemon () throw () |
void | setDaemon (bool flag) |
Static Public Methods | |
bool | interrupted () throw () |
bool | canceled () throw () |
void | sleep (unsigned long timeout) |
void | yield () throw () |
Reference | current () throw () |
There are two kinds of threads. Non-daemon threads and daemon threads. Non-daemon threads must be joined. Non-daemon threads must be joined, the lifetime of its task must be enclosed by the lifetime of the Thread object.
{ MyThread t; // Thread object's lifetime begins t.run(); // Task's effective lifetime begins t.join(); // Task's effective lifetime ends } // Thread object's lifetime begins
Daemon threads cannot be joined, they have the special property of allowing the effective lifetime of its task to exceed the lifetime of the Thread object.
{ MyThread t; // Thread object's lifetime begins t.setDaemon(true); t.run(); // Task's effective lifetime begins } // Thread object's lifetime begins // Task's effective lifetime ends
Using:
There are two way to use threads. The first is to extend the Thread class. This creates a heavy-wieght task; because the task is always associated with the overhead of a specific thread. Afterall, it is a Thread.
class MyThread : public Thread { public: virtual ~MyThread() throw() { } virtual void run() throw() { // perform task } }; int main() { try { MyThread t; t.start(); } catch(Synchronization_Exception&) { std::cerr << "error starting thread!" << std::endl; } }
Such a thread can be run using the start() function.
MyThread t; // Create the thread t.start(); // run the task t.join(); // wait for completion
The second way is create extend the Runnable class. This creates a light-weight task; because it is not associated with any one specific thread. This is an application of the Command pattern.
class MyRunnable : public Runnable { public: virtual ~MyRunnable() throw() { } virtual void run() throw() { // perform task } };
When Runnable objects are be submitted to Threads for execution they are wrapped with a reference counting object (called Handle) to simplify the task of keeping track of them. These wrappers are created for you automatically using the RunnablePtr() function.
// Submit a series of tasks to different threads Thread t[NUM_THREADS]; for(int i=0; i<NUM_THREADS; ++i) task.run( RunnablePtr(new MyTask()) );
An instance of a Runnable class can also be shared and submitted to several threads; rather than creating a new Runnable object for each thread.
// Submit a single task to different threads Thread t[NUM_THREADS]; Handle<MyTask> task = RunnablePtr(new MyTask()); for(int i=0; i<NUM_THREADS; ++i) task.run( task );
Threads are interruptible. Each thread has an interrupted status associated with it. This is set with the interrupt() method. A thread with an interrupted status will throw an Interrupted_Exception if it attempts a blocking operation (sleep(), Lockable::acquire(), Waitable::wait(), ...) and its interrupted status will be reset. Calling Thread::interrupted() will allow the currently executing thread to check and reset its interrupted status in a single operation.
Canceling:
Threads are Cancelable objects. A Thread extends the usual cancelation semantics to have the following meaning.
Disabling
A cancel()ed thread is placed into both interrupted and canceled status. This allows interrupt sensative code to respond to cancel() naturally. The Thread::canceled() function will report the canceled status of a thread and clear its interrupted status. However, canceled status can never be removed.
Exiting
A thread that has been cancel()ed is not forced to exit. It behaves as thread that has been interrupted would. By canceling a thread, it is sent a specific message that a request for it to exit has arrived. The thread may then respond by performing a graceful shutdown, performing whatever work is neccessary to do so.
By implementing the Cancelable interface to work with the interruption mechanism, it is possible to write very elegant code and to create some flexible task oriented frameworks.
|
Create a new thread object that can execute tasks in another thread of execution
|
|
Set the cancelation and interruption status of this thread.
Implements Cancelable. |
|
Tests whether the current Thread has been canceled, and clears the interrupted status.
|
|
Get a reference to the currently executing thread.
|
|
Get the priority of this Thread.
|
|
Interrupts this thread. If this thread is blocked when this method is called, the thread will abort that blocking operation with an Interrupted_Exception. Otherwise, the interrupted status of the thread is set. This status is cleared by one of two methods. The first is by attempting another blocking operation; this will clear the interrupted status and immediately abort the operation with an Interrupted_Exception. The second is to call isInterrupted() from the context of this thread. A thread is never started in an interrupted state. The interrupted status of a thread will be discarded when the thread starts. Interrupting a thread that is no longer running will have no effect other than setting the interrupt status permanently. When a thread exits, that status can no longer be cleared.
|
|
Tests whether the current Thread has been interrupt()ed, clearing its interruption status.
|
|
Tests whether this thread has been canceled. If called from the context of this thread, the interrupted status is cleared.
Implements Cancelable. |
|
Tests if this thread is a daemon thread.
|
|
Wait for the thread represented by this object to exit. Only one thread can wait on any other thread.
|
|
Convience method
|
|
From the context of this Thread, execute the task defined by the given Runnable object.
|
|
This can be implemented by subclasses to create a thread with a built in task. The default behavior is for the task to just return immediately, doing nothing. Implements Runnable. |
|
Change the status of this thread so that is now treated as a daemon thread. A daemon thread should not be joined, it will execute normally and its destructor can safely be invoked without first join()ing it. It will be join()ed by ZThreads when the program exits.
|
|
Change the priority of this Thread. This will change the actual priority of the thread when the OS supports it. If there is no real priority support, it's simulated.
|
|
Put the currently executing thread to sleep for a given amount of time.
|
|
From the context of this Thread, this method will run the Threads run() method. The default implementation for the run() method will throw an exception and exit immediately. However, subclasses can provide thier own, more useful, implementation of that method.
|
|
Cause the currently executing thread to yield, allowing the scheduler to assign some execution time to another thread. |