Threads Module User's Guide : PART II Concurrency Packages : Chapter 3 The Threading Package : Using Threads
Using Threads
This section uses a simple example to introduce and explain the concepts and classes involved in creating threads. You can find more examples in buildspace/examples/package-name. The following list gives the names of those examples and the classes and functions that they exercise:
activobj: RWThreadFunction, RWRunnableFunction, RWRunnableServer, RWTRunnableIOUFunction, RWTThreadIOUFunction
attrtest: RWRunnableSelf, RWThread, RWThreadAttribute, RWThreadFunction
balance: RWRunnableTrap
cancella: RWThreadFunction,RWRunnableSelf, RWCancellation
hello_g: RWThreadFunction
hello_m: RWThreadFunction
interupt: RWThreadFunction, RWRunnableSelf, RWCancellation
iouescro: RWThreadFunction, RWRunnableSelf
ioureslt: RWTThreadIOUFunction, RWRunnableSelf
ioutrap: RWThreadFunction, RWTThreadIOUFunction, RWRunnableSelf
prodcons: RWThreadFunction, RWRunnableSelf, RWRunnableTrap
rnbltrap: RWThreadFunction, RWRunnableTrap, RWRunnableSelf
servpool: RWTRunnableIOUFunction, RWRunnableSelf, RWServerPool
thrcreat: RWThreadFunction, RWRunnableSelf
threadid: RWThreadFunction, RWRunnableSelf, RWRunnableTrap
thrlocal: RWThreadFunction, RWRunnableSelf, RWTThreadLocal, RWRunnableTrap
thrstate: RWThreadFunction, RWRunnableSelf, RWCancellation
The scope and completeness of some examples in this guide are limited to ensure readability and satisfy size constraints. For this reason, you should also review the example programs distributed with the Threading package. See the appendix on file locations in the Building Your Applications document (rcbbd) for the exact location of the examples for your build.
Creating Threads
Example 1 creates a second thread of execution (main() is the first thread) and uses that thread to call a global function that prints the message “Hello World!” to the console.
Example 1 – Creating threads
#include <rw/thread/RWThreadFunction.h>
#include <iostream> // 1
 
using namespace std;
 
void hello(void) // 2
{
cout << "Hello World!” << endl;
}
 
int main()
{
RWThreadFunction myThread = RWThreadFunction::make(hello); // 3
myThread.start(); // 4
myThread.join(); // 5
return 0;
}
//1 Includes the header file containing the RWThreadFunction class declaration used in the example.
//2 Defines a global function to produce the message.
//3 Uses a Threading package global function to construct an RWThreadFunction runnable that executes the hello() function when started. That runnable object is bound to a local handle named myThread.
//4 Starts the runnable. This results in the creation of a new thread that then executes the hello() function.
//5 Waits for the newly created thread to finish execution.
The following sections take a closer look at some of the key components of this example.
Introducing the Runnable
In the Threading package, the runnable family of classes includes the basic mechanisms used to create, control, and monitor the threads of execution within your application. The RWThreadFunction class used in the example is a member of the runnable family; Figure 2 shows its relationship to the other runnable classes.
All runnable objects have a start() member and a virtual run() member. The run() member defines the work or activity to be performed by the runnable object. The start() member defines the form of dispatching to be used in executing the run() member. The dispatching is performed either synchronously by executing within the calling thread, or asynchronously by creating a new thread. Regardless of the dispatching mechanism, the run() member is always executed as a consequence of calling start().
The RWThreadFunction class used in the example is one of the asynchronous or threaded runnable classes. Instances of this class create a new thread of execution when start() is called. The RWThreadFunction class uses a functor to indicate to the new thread what to execute after it starts; in this case, the hello() function.
See “The Runnable Object Classes” for more information.
Explicitly Constructing Functors and Runnables
In the following code segment, a functor and threaded runnable instance are explicitly constructed:
Example 2 – Constructing a threaded runnable from a functor
// Construct a functor that invokes hello
RWTFunctor<void()> myFunctor = hello; // 1
// Construct a runnable that invokes functor
RWThreadFunction myThread; // 2
myThread = RWThreadFunction::make(myFunctor); // 3
//1 Constructs a handle instance for a functor object and binds it to the function hello().
//2 Constructs an empty RWThreadFunction handle instance.
//3 Constructs and initializes an RWThreadFunctionImp body instance, then binds that instance to the handle instance, myThread.
The code creates a threaded runnable that, when started, launches a thread that invokes the functor instance to execute the hello() function.