When your program creates a thread object, mutex, or condition variable, it can accept the default attributes for that object or specify an existing attributes object that contains particular attribute values. For a thread object, you can change some of its attributes after execution of the corresponding thread has begun---for example, you can change the thread's priority.
To create an attributes object, you can use one of the following routines, depending on the type of object to which the attributes apply:
These routines create an attributes object containing default values for the individual attributes. To modify any attribute values in an attributes object, use one of the "attr_set" routines, such as pthread_attr_setinheritsched(), described in later sections.
Creating an attributes object (or changing the values in an attributes object) does not affect the attributes of existing thread objects, mutexes, and condition variables.
To destroy an attributes object, use one of the following routines:
Deleting an attributes object does not affect the attributes of objects
previously created with that attributes object.
2.3 Thread Objects and Operations
Operations on threads take place with respect to a thread object. A thread object is a data structure maintained by DECthreads that contains the attribute information and DECthreads state information about a thread.
The following sections describe these operations on threads:
Creating a thread means directing DECthreads to create a thread object and to assign a unique thread identifier to the thread object. The thread object encapsulates attribute information about the thread and DECthreads' own state information about the thread. After a thread has been created, DECthreads has all the information it requires to start a distinct sequence of execution with this process.
Starting a thread means DECthreads causes a start routine, with its argument, to be called on some CPU within this system.
Your program creates a thread using the pthread_create() routine. This routine creates a thread object based on the settings of a specified thread attributes object, which your program must have previously created and initialized. Otherwise, without specifying a thread attributes object, you can create a new thread that has DECthreads default attributes.
DECthreads creates a thread in the ready state and prepares the thread to begin executing its start routine, the function passed to the pthread_create() routine. Depending on the presence of other threads and their scheduling and priority attributes, the new thread might start executing immediately. The new thread can also preempt its creator, depending on the two threads' respective scheduling and priority attributes. The caller of pthread_create() can synchronize with the new thread using the pthread_join() routine or using any mutually agreed upon mutexes or condition variables.
For the duration of the new thread's existence, DECthreads maintains and manages the thread object and other thread state overhead. A thread exists until it is both terminated and detached. (See Section 2.3.3 and Section 2.3.4 for more information about terminating and detaching threads.)
DECthreads assigns each new thread a thread identifier, which DECthreads writes into the address specified as the pthread_create() routine's thread argument. DECthreads writes the new thread's thread identifier before the new thread executes.
By default, the new thread's scheduling policy and priority are inherited from the creating thread---that is, by default, the pthread_create() routine ignores the scheduling policy and priority set in the specified thread attributes object. Thus, to create a thread that is subject to the scheduling policy and priority set in the specified thread attributes object, before calling pthread_create() your program must use the pthread_attr_setinheritsched() routine to set the inherit thread attributes object's scheduling attribute to PTHREAD_EXPLICIT_SCHED.
You can create a thread that is detached. To do so, create a thread using a thread attributes object whose detachstate attribute has been set, using the pthread_attr_setdetach() routine, to PTHREAD_CREATE_DETACHED. This is useful for creating a thread that your program knows will not join with any other thread. That is, when such a thread terminates, DECthreads automatically destroys the thread and its thread object.
For more detailed information about thread creation, see the reference
description of the pthread_create() routine in Part 2.
2.3.2 Setting the Attributes of a New Thread
When creating a thread, your program can optionally specify the attributes of the new thread using a thread attributes object. To do so, your program must:
After your program creates a thread attributes object, that object can be reused for each new thread that the program creates. For the details about creating and deleting a thread attributes object, see the descriptions in Part 2 of the pthread_attr_create() and pthread_attr_delete() routines.
Using the thread attributes object, your program can specify these attributes of a new thread:
The inherit scheduling attribute's value specifies whether the new thread inherits the settings of its scheduling priority attribute and scheduling parameters attribute from the creating thread (the default behavior), or uses the scheduling attributes stored in the attributes object. Inheriting these settings from the creating thread is the default behavior, or you can specify the same by setting the thread attributes object's inherit scheduling attribute to PTHREAD_INHERIT_SCHED. To use the setting in the attributes objects, set the inherit scheduling attribute to PTHREAD_EXPLICIT_SCHED.
Use the pthread_attr_setinheritsched() routine to set the
thread attributes object's inherit scheduling attribute.
188.8.131.52 Setting the Scheduling Policy Attribute
The scheduling policy attribute describes how DECthreads schedules the new thread for execution relative to the other threads in the process.
A thread has one of the following scheduling policies:
Use either of two techniques to set a thread attributes object's scheduling policy attribute:
Section 2.3.6 describes and shows the effect of the scheduling policy on
184.108.40.206.2 Comparing Throughput and Real-Time Policies
The default throughput scheduling policy is intended to be an "adaptive" policy, giving each thread an opportunity to execute based on its behavior. That is, for a thread that doesn't execute often, DECthreads tends to give it high access to the processor because it isn't greatly affecting other threads. On the other hand, DECthreads tends to schedule with less preference any compute-bound threads with throughput scheduling policy.
This yields a responsive system in which all threads with throughput scheduling policy get a chance to run fairly frequently. It also has the effect of automatically resolving priority inversions, because over time any threads that have received less processing time (among those with throughput scheduling policy) will rise in preference while the running thread drops, and eventually the inversion is reversed.
The FIFO and RR scheduling policies are considered "real-time" policies, because they require DECthreads to schedule such threads strictly by the specified priority. Because threads that use real-time scheduling policies require additional DECthreads overhead, incautious use of the FIFO or RR policies can cause the performance of the application to suffer.
If relative priorities of threads are important to your
application---that is, if a compute-bound thread really requires
consistently predictable execution---then create those threads
using either the FIFO or RR scheduling policy. However, use of
"real-time" policies can expose the application to unexpected
performance problems, such as priority inversions, and therefore their
use should be avoided in most applications.
220.127.116.11.3 Portability of Scheduling Policy Settings
Only the SCHED_FIFO and SCHED_RR scheduling policies are portable across POSIX.1c-conformant implementations. The other scheduling policies are DECthreads extensions to the POSIX.1c standard.
NoteThe SCHED_OTHER identifier is portable, but the POSIX.1c standard does not specify the behavior that it signifies. For example, on non-DECthreads platforms the SCHED_OTHER scheduling policy could be identical to the SCHED_FIFO or SCHED_RR policy.
The scheduling parameters attribute specifies the execution priority of a thread. (Although the terminology and format are designed to allow adding more scheduling parameters in the future, only priority is currently defined.) The priority is an integer value, but each policy can allow only a restricted range of priority values. You can determine the range for any policy by calling the sched_get_priority_min() or sched_get_priority_max() routines. DECthreads also supports a set of nonportable symbols designating the priority range for each policy, as follows:
Section 2.3.6 describes how to specify a priority between the minimum and maximum values, and it also discusses how priority affects thread scheduling.
Use either of two techniques to set a thread attributes object's scheduling parameters attribute:
The stacksize attribute represents the minimum size (in bytes) of the memory required for a thread's stack. To increase or decrease the size of the stack for a new thread, call the pthread_attr_setstacksize() routine and use this thread attributes object when creating the thread and stack. You must specify at least PTHREAD_STACK_MIN bytes.
After a thread has been created, your program cannot change the size of
the thread's stack. See Section 3.4.1 for more information about sizing
18.104.22.168 Setting the Stack Address Attribute
The stack address attribute represents the location or address of a region of memory that your program allocates to use as a thread's stack. The value of the stack address attribute represents the origin of the thread's stack. However, please be aware that the actual address you specify, relative to the stack memory you have allocated, is inherently nonportable.
To set the address of the stack origin for a new thread, call the
pthread_attr_setstackaddr() routine, specifying an initialized thread attributes object as an argument, and use the thread attributes object when creating the new thread. Use the pthread_attr_getstackaddr() routine to obtain the value of the stack address attribute of an initialized thread attributes object.
After a thread has been created, your program cannot change the address of the thread's stack.
You cannot create two concurrent threads that use the same stack address.
The system uses an unspecified (and varying) amount of the stack to
"bootstrap" a newly created thread.
22.214.171.124 Setting the Guardsize Attribute
The guardsize attribute represents the minimum size (in bytes) of the guard area for the stack of a thread. A guard area can help a multithreaded program detect overflow of a thread's stack. A guard area is a region of no-access memory that DECthreads allocates at the overflow end of the thread's stack. When the thread attempts to access a memory location within this region, a memory addressing violation occurs.
A new thread can be created using a thread attributes object with a default guardsize attribute value. This value is platform dependent, but will always be at least one "hardware protection unit" (that is, at least one page; non-zero values are rounded up to the next integral page size). For more information, see this guide's platform-specfic appendixes.
DECthreads allows your program to specify the size of a thread stack guard area for two reasons:
To set the guardsize attribute of a thread attributes object, call the pthread_attr_setguardsize() routine. To obtain the value of the guardsize attribute in a thread attributes object, call the pthread_attr_getguardsize() routine.
The pthread_attr_setguardsize() and
pthread_attr_getguardsize() routines replace (and are
equivalent to) the pthread_attr_setguardsize_np() and
pthread_attr_getguardsize_np() routines, respectively, that
were available in previous DECthreads releases. The new routines
provide a standardized and portable interface, specified by the Single
UNIX Specification, Version 2; however, the older routines remain
126.96.36.199 Setting the Contention Scope Attribute
When creating a thread, you can specify the set of threads with which this thread competes for processing resources. This set of threads is called the thread's contention scope.
A thread attributes object includes a contention scope attribute. The contention scope attribute specifies whether the new thread competes for processing resources only with other threads in its own process, called process contention scope, or with all threads on the system, called system contention scope.
Use the pthread_attr_setscope() routine to set an initialized thread attributes object's contention scope attribute. Use the pthread_attr_getscope() routine to obtain the value of the contention scope attribute of an initialized thread attributes object.
In the thread attributes object, set the contention scope attribute's value to PTHREAD_SCOPE_PROCESS to specify process contention scope, or set the value to PTHREAD_SCOPE_SYSTEM to specify system contention scope.
DECthreads selects at most one thread to execute on each processor at any point in time. DECthreads resolves the contention based on each thread's scheduling attributes (for example, priority) and scheduling policy (for example, round-robin).
A thread created using a thread attributes object whose contention scope attribute is set to PTHREAD_SCOPE_PROCESS contends for processing resources with other threads within its own process that also were created with PTHREAD_SCOPE_PROCESS. It is unspecified how such threads are scheduled relative to threads in other processes or threads in the same process that were created with PTHREAD_SCOPE_SYSTEM contention scope.
A thread created using a thread attributes object whose contention scope attribute is set to PTHREAD_SCOPE_SYSTEM contends for processing resources with other threads in any process that also were created with PTHREAD_SCOPE_SYSTEM.
Whether process contention scope and system contention scope are available for your program's threads depends on the host operating system. The following table summarizes DECthreads support for thread contention scope by operating system:
|Operating System||Available Thread Contention Scopes|| Default Thread
NoteOn DIGITAL UNIX systems:
When a process contention scope thread creates a system contention scope thread that uses the default inheritance of scheduling attributes, the creation can fail with an [EPERM] error condition. This is because system contention scope threads can exceed "default" priority only if the process is running with root privileges.
Terminating a thread means to cause a thread to end its execution. This can occur for any of the following reasons:
When a thread terminates, DECthreads performs these actions:
NoteIf the thread terminated by returning from its start routine normally and the start routine does not provide a return value, the results obtained by joining with that thread are unpredictable.