| Team-FLY |
12.6 Thread Attributes
POSIX takes an object-oriented approach to representation and assignment of properties by encapsulating properties such as stack
Table 12.3 shows the settable properties of thread attributes and their associated functions. Other entities, such as condition
Table 12.3. Summary of settable properties for POSIX thread attribute objects.
The
pthread_attr_init
function initializes a thread attribute object with the default values. The
pthread_attr_destroy
function sets the value of the attribute object to be invalid. POSIX does not specify the behavior of the object after it has been
SYNOPSIS #include <pthread.h> int pthread_attr_destroy(pthread_attr_t *attr); int pthread_attr_init(pthread_attr_t *attr); POSIX:THR
If successful,
pthread_attr_destroy
and
pthread_attr_init
return 0. If
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 . SYNOPSIS #include <pthread.h> int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); POSIX:THR 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 .
int error, fd;
pthread_attr_t tattr;
pthread_t tid;
if (error = pthread_attr_init(&tattr))
fprintf(stderr, "Failed to create attribute object: %s\n",
strerror(error));
else if (error = pthread_attr_setdetachstate(&tattr,
PTHREAD_CREATE_DETACHED))
fprintf(stderr, "Failed to set attribute state to detached: %s\n",
strerror(error));
else if (error = pthread_create(&tid, &tattr, processfd, &fd))
fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
12.6.2 The thread stack
A thread has a stack whose location and size are
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. SYNOPSIS #include <pthread.h> int pthread_attr_getstack(const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize); int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); POSIX:THR,TSA,TSS 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
SYNOPSIS #include <pthread.h> int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, size_t *restrict guardsize); int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); POSIX:THR,XSI
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.
12.6.3 Thread scheduling
The
SYNOPSIS #include <pthread.h> int pthread_attr_getscope(const pthread_attr_t *restrict attr, int *restrict contentionscope); int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope); POSIX:THR,TPS 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.
int error;
int fd;
pthread_attr_t tattr;
pthread_t tid;
if (error = pthread_attr_init(&tattr))
fprintf(stderr, "Failed to create an attribute object:%s\n",
strerror(error));
else if (error = pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM))
fprintf(stderr, "Failed to set scope to system:%s\n",
strerror(error));
else if (error = pthread_create(&tid, &tattr, processfd, &fd))
fprintf(stderr, "Failed to create a thread:%s\n", strerror(error));
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. SYNOPSIS #include <pthread.h> int pthread_attr_getinheritsched(const pthread_attr_t *restrict attr, int *restrict inheritsched); int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched); POSIX:THR,TPS 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. SYNOPSIS #include <pthread.h> int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, struct sched_param *restrict param); int pthread_attr_setschedparam(pthread_attr_t *restrict attr, const struct sched_param *restrict param); POSIX:THR 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.
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 parameters ”read 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 .
#define HIGHPRIORITY 10
int fd;
pthread_attr_t *tattr;
pthread_t tid;
struct sched_param tparam;
if ((tattr = makepriority(HIGHPRIORITY))) {
perror("Failed to create the attribute object");
else if (error = pthread_create(&tid, tattr, dothis, &fd))
fprintf(stderr, "Failed to create dothis thread:%s\n", strerror(error));
Threads of the same priority
Program 12.10 makepriority.cA function to create a thread attribute object with the specified priority .
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
pthread_attr_t *makepriority(int priority) { /* create attribute object */
pthread_attr_t *attr;
int error;
struct sched_param param;
if ((attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t))) == NULL)
return NULL;
if (!(error = pthread_attr_init(attr)) &&
!(error = pthread_attr_getschedparam(attr, ¶m))) {
param.sched_priority = priority;
error = pthread_attr_setschedparam(attr, ¶m);
}
if (error) { /* if failure, be sure to free memory */
free(attr);
errno = error;
return NULL;
}
return attr;
}
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. SYNOPSIS #include <pthread.h> int pthread_attr_getschedpolicy(const pthread_attr_t *restrict attr, int *restrict policy); int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); POSIX:THR If successful, these functions return 0. If unsuccessful, they return a nonzero error code. No mandatory errors are defined for these functions. |
| Team-FLY |