Threads Module User's Guide : PART II Concurrency Packages : Chapter 3 The Threading Package : The Runnable Object Classes : Defining a Runnable’s Task
Defining a Runnable’s Task
In addition to being distinguished by their dispatching behavior, the runnable object can also be identified according to the mechanism used to define its “task” or “work.” Some runnables accept a functor object for execution, while others accept and execute other runnables objects.
Functor-Based Runnables
A functor is an object used to encapsulate a function call. Each functor keeps a pointer to the function and copies of the argument values that are to be passed to the function. Invoking a functor produces a call to the function.
The Functor package functors are an ideal mechanism for defining the work to be performed by a runnable. Each functor instance is invoked using a common, inherited interface that remains the same regardless of the actual function signature or argument values.
A functor-based runnable redefines the run() member to invoke a functor instance stored within the runnable. With this capability, you do not have to sub-class or use other intrusive techniques to customize the execution behavior of a runnable. The functor-based runnables allow you to dynamically specify the functions you want to execute when a runnable is started.
The functor-based runnables include:
RWRunnableFunction — A synchronous runnable class that uses a functor to execute a function whose return value, if any, can be ignored.
RWTRunnableIOUFunction — A synchronous class that uses a functor to execute a function whose return value is to be captured in an IOU. IOUs are a mechanism used to retrieve and wait for the result of an asynchronous operation. See “The IOU Classes” of the Interthread Communication Package for more information.
RWThreadFunction — An asynchronous, threaded runnable that creates a new thread to invoke a functor that executes a function whose return value, if any, can be ignored.
RWTThreadIOUFunction — An asynchronous, threaded runnable that creates a new thread to invoke a functor that executes a function whose return value is to be captured in an IOU.
For more information on functor-based runnables, see “Creating Functor-based Runnables.” For more information on functors, see Chapter 8, “The Functor Package.”
Runnable Servers
In addition to the functor-based runnable classes, the Threading package also has runnable classes that accept other runnable objects for execution. This type of runnable is called a runnable server.
A runnable server is a threaded runnable that accepts and queues any number of runnable objects and executes them within its own internal thread or threads. The runnable server classes are:
RWRunnableServer
RWServerPool
These classes are covered in detail in “The Server Classes.”
Guard Functors
You can also specify a guard functor for each runnable instance that you pass to a runnable server. This guard functor is invoked by the runnable server prior to dequeuing a runnable for execution. If the function called by the functor returns false, the runnable is left on the internal runnable queue. Otherwise, if the function returns true, the runnable is dequeued and dispatched.
The runnable server traverses its input queue, evaluating each runnable’s guard until an executable runnable is found. If none of the currently queued runnables can execute, the server waits for another runnable to be queued, and when that happens, repeats the guard evaluation process.
Functors are covered in detail in Chapter 8, “The Functor Package.”