Provide platform-independent utilities related to threading.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide platform-independent utilities related to threading.
-
- Classes:
-
- See also:
- Component bslmt_threadattributes, Component bslmt_configuration
-
- Description:
- This component defines a utility
struct
, bslmt::ThreadUtil
, that serves as a name space for a suite of pure functions to create threads, join them (make one thread block and wait for another thread to exit), manipulate thread handles, manipulate the current thread, and (on some platforms) access thread-local storage.
-
- Creating a Simple Thread with Default Attributes:
- Clients call
bslmt::ThreadUtil::create()
to create threads. Threads may be started using a "C" linkage function pointer (of a type defined by bslmt::ThreadUtil::ThreadFunction
) and a void
pointer to userData
to be passed to the function; or an "invokable" object of parameterized type (any copy-constructible type on which operator()
may be invoked). The invoked function becomes the main driver for the new thread; when it returns, the thread terminates.
-
- Thread Identity:
- A thread is identified by an object of the opaque type
bslmt::ThreadUtil::Handle
. A handle of this type is returned when a thread is created (using bslmt::ThreadUtil::create
). A client can also retrieve a Handle
for the "current" thread via the self
method: Several thread manipulation functions in bslmt::ThreadUtil
take a thread handle, or pointer to a thread handle, as an argument. To facilitate compatibility with existing systems and allow for non-portable operations, clients also have access to the bslmt::ThreadUtil::NativeHandle
type, which exposes the underlying, platform-specific thread identifier type: Note that the returned native handle may not be a globally unique identifier for the thread, and, e.g., should not be converted to an integer identifier, or used as a key in a map.
-
- Setting Thread Priorities:
bslmt::ThreadUtil
allows clients to configure the priority of newly created threads by setting the inheritSchedule
, schedulingPolicy
, and schedulingPriority
of a thread attributes object supplied to the create
method. The range of legal values for schedulingPriority
depends on both the platform and the value of schedulingPolicy
, and can be obtained from the getMinSchedulingPriority
and getMaxSchedulingPriority
methods. Both schedulingPolicy
and schedulingPriority
are ignored unless inheritSchedule
is false
(the default value is true
). Note that not only is effective setting of thread priorities workable on only some combinations of platforms and user privileges, but setting the thread policy and priority appropriately for one platform may cause thread creation to fail on another platform. Also note that an unset thread priority may be interpreted as being outside the valid range defined by [ getMinSchedulingPriority(policy), getMaxSchedulingPriority(policy) ]
. Platform Restrictions
------------ --------------------------------------------------------------
Solaris 5.10 None.
Solaris 5.11 Spawning of threads fails if 'schedulingPolicy' is
'BSLMT_SCHED_FIFO' or 'BSLMT_SCHED_RR'. Thread priorities
should not be used on Solaris 5.11 as it is not clear that
they have any detectable effect. Note that
'getMinSchedulingPriority' and 'getMaxSchedulingPriority'
return different values than on Solaris 5.10.
AIX For non-privileged clients, spawning of threads fails if
'schedulingPolicy' is 'BSLMT_SCHED_FIFO' or 'BSLMT_SCHED_RR'.
Linux Non-privileged clients *can* *not* make effective use of
thread priorities -- spawning of threads fails if
'schedulingPolicy' is 'BSLMT_SCHED_FIFO' or 'BSLMT_SCHED_RR',
and 'getMinSchedulingPriority == getMaxSchedulingPriority' if
the policy has any other value.
Darwin Non-privileged clients *can* *not* make effective use of
thread priorities -- there is no observable difference in
urgency between high priority and low priority threads.
Spawning of threads does succeed, however, for all scheduling
policies.
Windows Clients *can* *not* make effective use of thread priorities --
'schedulingPolicy', 'schedulingPriority', and
'inheritSchedule' are ignored for all clients.
-
- Supported Clock-Types:
bsls::SystemClockType
supplies the enumeration indicating the system clock on which timeouts supplied to other methods should be based. If the clock type indicated at construction is bsls::SystemClockType::e_REALTIME
, the absTime
argument passed to the timedWait
method of the various synchronization primitives offered in bslmt
should be expressed as an absolute offset since 00:00:00 UTC, January 1, 1970 (which matches the epoch used in bsls::SystemTime::now(bsls::SystemClockType::e_REALTIME)
. If the clock type indicated at construction is bsls::SystemClockType::e_MONOTONIC
, the absTime
argument passed to the timedWait
method of the various synchronization primitives offered in bslmt
should be expressed as an absolute offset since the epoch of this clock (which matches the epoch used in bsls::SystemTime::now(bsls::SystemClockType::e_MONOTONIC)
.
-
- Usage:
- This section illustrates the intended use of this component.
-
- Example 1: Creating a Simple Thread with Default Attributes:
- In this example, we create a thread using the default attribute settings. Upon creation, the thread executes the user-supplied C-linkage function
myThreadFunction
that counts 5 seconds before terminating:
- First, we create a function that will run in the spawned thread:
extern "C" void *myThreadFunction(void *)
{
for (int i = 0; i < 3; ++i) {
bslmt::ThreadUtil::microSleep(0, 1);
bsl::cout << "Another second has passed." << bsl::endl;
}
return 0;
}
Now, we show how to create and join the thread.
- After creating the thread, the
main
routine joins the thread, which, in effect, causes main
to wait for execution of myThreadFunction
to complete, and guarantees that the output from main
will follow the last output from the user-supplied function: Finally, the output of this program is: Another second has passed.
Another second has passed.
Another second has passed.
A three second interval has elapsed.
-
- Example 2: Creating a Simple Thread with User-Specified Attributes:
- In this example, we will choose to override the default thread attribute values.
- The attributes of a thread can be specified explicitly by supplying a
bslmt::ThreadAttributes
object to the create
method. For instance, we could specify a smaller stack size for a thread to conserve system resources if we know that we will require not require the platform's default stack size.
- First, we define our thread function, noting that it doesn't need much stack space:
extern "C" void *mySmallStackThreadFunction(void *threadArg)
{
char *initValue = (char *)threadArg;
char Small[8];
bsl::memset(&Small[0], *initValue, 8);
return 0;
}
Finally, we show how to create a detached thread running the function just created with a small stack size:
-
- Example 3: Setting Thread Priorities:
- In this example we demonstrate creating 3 threads with different priorities. We use the
convertToSchedulingPriority
function to translate a normalized, floating-point priority in the range [ 0.0, 1.0 ]
to an integer priority in the range [ getMinSchedulingPriority, getMaxSchedulingPriority ]
to set the schedulingPriority
attribute.
Typedef Documentation
bslmt_ThreadFunction
is an alias for a function type taking a single void
pointer argument and returning void *
. Such functions are suitable to be specified as thread entry-point functions to bslmt::ThreadUtil::create
. Note that create
also accepts any invokable C++ "functor" object.
bslmt_KeyDestructorFunction
is an alias for a function type taking a single void
pointer argument and returning void
. Such functions are suitable to be specified as thread-specific key destructor functions to bslmt::ThreadUtil::createKey
.