12.6 Thread AttributesPOSIX takes an object-oriented approach to representation and assignment of properties by encapsulating properties such as stack size and scheduling policy into an object of type pthread_attr_t. The attribute object affects a thread only at the time of creation. You first create an attribute object and associate properties, such as stack size and scheduling policy, with the attribute object. You can then create multiple threads with the same properties by passing the same thread attribute object to pthread_create. By grouping the properties into a single object, POSIX avoids pthread_create calls with a large number of parameters.Chapter 13 discusses these synchronization mechanisms.
If successful, pthread_attr_destroy and pthread_attr_init return 0. If unsuccessful, these functions return a nonzero error code. The pthread_attr_init function sets errno to ENOMEM if there is not enough memory to create the thread attribute object.Most of the get/set thread attribute functions have two parameters. The first parameter is a pointer to a thread attribute object. The second parameter is the new value of the attribute for a set operation or a pointer to location to hold the value for a get operation. The pthread_attr_getstack and pthread_attr_setstack each have one additional parameter. 12.6.1 The thread stateThe pthread_attr_getdetachstate function examines the state of an attribute object, and the pthread_attr_setdetachstate function sets the state of an attribute object. The possible values of the thread state are PTHREAD_CREATE_JOINABLE and PTHREAD_CREATE_DETACHED. The attr parameter is a pointer to the attribute object. The detachstate parameter corresponds to the value to be set for pthread_attr_setdetachstate and to a pointer to the value to be retrieved for pthread_attr_getdetachstate.
If successful, these functions return 0. If unsuccessful, they return a nonzero error code. The pthread_attr_setdetachstate function sets errno to EINVAL if detachstate is invalid.Detached threads release their resources when they terminate, whereas joinable threads should be waited for with a pthread_join. A thread that is detached cannot be waited for with a pthread_join. By default, threads are joinable. You can detach a thread by calling the pthread_detach function after creating the thread. Alternatively, you can create a thread in the detached state by using an attribute object with thread state PTHREAD_CREATE_DETACHED. Example 12.15The following code segment creates a detached thread to run processfd.
12.6.2 The thread stackA thread has a stack whose location and size are user-settable, a useful property if the thread stack must be placed in a particular region of memory. To define the placement and size of the stack for a thread, you must first create an attribute object with the specified stack attributes. Then, call pthread_create with this attribute object.The pthread_attr_getstack function examines the stack parameters, and the pthread_attr_setstack function sets the stack parameters of an attribute object. The attr parameter of each function is a pointer to the attribute object. The pthread_attr_setstack function takes the stack address and stack size as additional parameters. The pthread_attr_getstack takes pointers to these items.
If successful, the pthread_attr_getstack and pthread_attr_setstack functions return 0. If unsuccessful, these functions return a nonzero error code. The pthread_attr_setstack function sets errno to EINVAL if stacksize is out of range.POSIX also provides functions for examining or setting a guard for stack overflows if the stackaddr has not been set by the user. The pthread_attr_getguardsize function examines the guard parameters, and the pthread_attr_setguardsize function sets the guard parameters for controlling stack overflows in an attribute object. If the guardsize parameter is 0, the stack is unguarded. For a nonzero guardsize, the implementation allocates additional memory of at least guardsize. An overflow into this extra memory causes an error and may generate a SIGSEGV signal for the thread.
If successful, pthread_attr_getguardsize and pthread_attr_setguardsize return 0. If unsuccessful, these functions return a nonzero error code. They return EINVAL if the attr or guardsize parameter is invalid. Guards require the POSIX:THR Extension and the POSIX:XSI Extension. 12.6.3 Thread schedulingThe contention scope of an object controls whether the thread competes within the process or at the system level for scheduling resources. The pthread_attr_getscope examines the contention scope, and the pthread_attr_setscope sets the contention scope of an attribute object. The attr parameter is a pointer to the attribute object. The contentionscope parameter corresponds to the value to be set for pthread_attr_setscope and to a pointer to the value to be retrieved for pthread_attr_getscope. The possible values of the contentionscope parameter are PTHREAD_SCOPE_PROCESS and PTHREAD_SCOPE_SYSTEM.
If successful, pthread_attr_getscope and pthread_attr_setscope return 0. If unsuccessful, these functions return a nonzero error code. No mandatory errors are defined for these functions. Example 12.16The following code segment creates a thread that contends for kernel resources.
POSIX allows a thread to inherit a scheduling policy in different ways. The pthread_attr_getinheritsched function examines the scheduling inheritance policy, and the pthread_attr_setinheritsched function sets the scheduling inheritance policy of an attribute object.The attr parameter is a pointer to the attribute object. The inheritsched parameter corresponds to the value to be set for pthread_attr_setinheritsched and to a pointer to the value to be retrieved for pthread_attr_getinheritsched. The two possible values of inheritsched are PTHREAD_INHERIT_SCHED and PTHREAD_EXPLICIT_SCHED. The value of inheritsched determines how the other scheduling attributes of a created thread are to be set. With PTHREAD_INHERIT_SCHED, the scheduling attributes are inherited from the creating thread and the other scheduling attributes are ignored. With PTHREAD_EXPLICIT_SCHED, the scheduling attributes of this attribute object are used.
If successful, these functions return 0. If unsuccessful, they return a nonzero error code. No mandatory errors are defined for these functions.The pthread_attr_getschedparam function examines the scheduling parameters, and the pthread_attr_setschedparam sets the scheduling parameters of an attribute object. The attr parameter is a pointer to the attribute object. The param parameter is a pointer to the value to be set for pthread_attr_setschedparam and a pointer to the value to be retrieved for pthread_attr_getschedparam. Notice that unlike the other pthread_attr_set functions, the second parameter is a pointer because it corresponds to a structure rather than an integer. Passing a structure by value is inefficient.
If successful, these functions return 0. If unsuccessful, they return a nonzero error code. No mandatory errors are defined for these functions.The scheduling parameters depend on the scheduling policy. They are encapsulated in a struct sched_param structure defined in sched.h. The SCHED_FIFO and SCHED_RR scheduling policies require only the sched_priority member of struct sched_param. The sched_priority field holds an int priority value, with larger priority values corresponding to higher priorities. Implementations must support at least 32 priorities.Program 12.10 shows a function that creates a thread attribute object with a specified priority. All the other attributes have their default values. Program 12.10 returns a pointer to the created attribute object or NULL if the function failed, in which case it sets errno. Program 12.10 illustrates the general strategy for changing parametersread the existing values first and change only the ones that you need to change. Example 12.17The following code segment creates a dothis thread with the default attributes, except that the priority is HIGHPRIORITY.
Threads of the same priority compete for processor resources as specified by their scheduling policy. The sched.h header file defines SCHED_FIFO for first-in-first-out scheduling, SCHED_RR for round-robin scheduling and SCHED_OTHER for some other policy. One additional scheduling policy, SCHED_SPORADIC, is defined for implementations supporting the POSIX:SS Process Sporadic Server Extension and the POSIX:TSP Thread Sporadic Server Extension. Implementations may also define their own policies. Program 12.10 makepriority.cA function to create a thread attribute object with the specified priority.
First-in-first-out scheduling policies (e.g., SCHED_FIFO) use a queue for threads in the runnable state at a specified priority. Blocked threads that become runnable are put at the end of the queue corresponding to their priority, whereas running threads that have been preempted are put at the front of their queue.Round-robin scheduling (e.g., SCHED_RR) behaves similarly to first-in-first-out except that when a running thread has been running for its quantum, it is put at the end of the queue for its priority. The sched_rr_get_interval function returns the quantum.Sporadic scheduling, which is similar to first-in-first-out, uses two parameters (the replenishment period and the execution capacity) to control the number of threads running at a given priority level. The rules are reasonably complex, but the policy allows a program to more easily regulate the number of threads competing for the processor as a function of available resources.Preemptive priority policy is the most common implementation of SCHED_OTHER. A POSIX-compliant implementation can support any of these scheduling policies. The actual behavior of the policy in the implementation depends on the scheduling scope and other factors.The pthread_attr_getschedpolicy function gets the scheduling policy, and the pthread_attr_setschedpolicy function sets the scheduling policy of an attribute object. The attr parameter is a pointer to the attribute object. For the function pthread_attr_setschedpolicy, the policy parameter is a pointer to the value to be set; for pthread_attr_getschedpolicy, it is a pointer to the value to be retrieved. The scheduling policy values are described above.
If successful, these functions return 0. If unsuccessful, they return a nonzero error code. No mandatory errors are defined for these functions. |