Thread Attributes
In a POSIX implementation, if we want to generate a thread that does not have the default attributes (obtained by setting the second parameter of the pthread_create call to NULL), an attribute object is used. To use an attribute object, it must first be initialized . This is accomplished using the library call pthread_attr_init (see Table 11.5).
Table 11.5. The pthread_attr_init Library Function.
Include File(s) |
Manual Section |
3 |
|||
Summary |
int pthread_attr_init ( pthread_attr_t *attr ); |
||||
Return |
Success |
Failure |
Sets errno |
||
Nonzero |
The pthread_attr_init library function has a single argument, a reference to a previously allocated pthread_attr_t type object. If the call is successful, it returns a 0 and initializes the referenced attribute object with the default value for each attribute (see Table 11.6). A return of ENOMEM (12) indicates the system does not have sufficient memory to initialize the thread attribute object.
Once initialized, individual attribute values can be modified (see the following discussion). The attribute object is passed as the second argument to the pthread_create call. The newly created thread will have the specified attributes. The attribute object is independent of the thread, and changes to the attribute object after a thread has been created are not reflected in existing threads. Once established, a thread attribute object can be used in the generation of multiple threads. Thread attributes and their default values are shown in Table 11.6.
Table 11.6. Thread Attributes and Default Settings.
Attribute |
Default |
Comments |
---|---|---|
detachstate |
PTHREAD_CREATE_JOINABLE |
A nondetached thread that can be joined by other threads. The thread's resources are not freed until a call is made to pthread_join or the calling process exits. |
inheritsched |
PTHREAD_EXPLICIT_SCHED |
Indicates whether or not scheduling attributes are inherited from parent thread or set explicitly by the attribute object. |
schedparam |
Scheduling parameters (priority). |
|
schedpolicy |
SCHED_OTHER |
Scheduling is determined by the system (most often some sort of timesharing ). Note the missing PTHREAD_prefix. |
scope |
PTHREAD_SCOPE_SYSTEM |
Scope of scheduling contentionwith all threads in same process or all processes in the system. |
As presented, if the user wants a thread to have different characteristics, he or she should first initialize the attribute object using the pthread_attr_init library call and then change the attributes he or she wants to be different. Each attribute listed in Table 11.7 has an associated pthread_attr_setxxx and pthread_attr_getxxx function call that will act upon the attribute object.
Table 11.7. Thread Attribute Set and Get functions
Attribute |
Set and get Calls |
Defined Constants [11] for the 2nd setxxx parameter |
---|---|---|
int pthread_attr_setdetachstate ( pthread_attr_t *attr, int detachstate); |
PTHREAD_CREATE_JOINABLE |
|
detachstate |
||
int pthread_attr_getdetachstate ( const pthread_attr_t *attr, int *detachstate); |
PTHREAD_CREATE_DETACHED |
|
int pthread_attr_setinheritsched ( pthread_attr_t *attr, int inheritsched |
PTHREAD_EXPLICIT_SCHED |
|
inheritsched |
||
int pthread_attr_getinheritsched ( const pthread_attr_t *attr, int *inheritsched) ; |
PTHREAD_INHERIT_SCHED |
|
int pthread_attr_setschedparam ( pthread_attr_t *attr, const struct sched_param *param); |
||
Schedparam |
Reference to valid sched_param [12] structure with its sched_priority member assigned a valid priority. |
|
int pthread_attr_getschedparam ( pthread_attr_t *attr, const struct sched_param *param); |
||
int pthread_attr_setschedpolicy ( pthread_attr_t *attr, int policy); |
SCHED_OTHER [13] SCHED_FIFO SCHED_RR |
|
Schedpolicy |
||
int pthread_attr_getschedpolicy ( const pthread_attr_t *attr, int *policy); |
||
int pthread_attr_setscope ( pthread_attr_t *attr, int contentionscope); |
PTHREAD_SCOPE_SYSTEM |
|
Scope |
||
int pthread_attr_getscope ( const pthread_attr_t *attr, int *contentionscope); |
PTHREAD_SCOPE_PROCESS |
[11] The highlighted values are the default.
[12] The sched_param structure is found in the include file , which is included by the file.
[13] Only processes with superuser privileges can specify SCHED_FIFO or SCHED_RR.
If in Program 11.1 we wanted to use the thread attribute object to indicate our threads be detached (that is, the thread would exit as soon as it has completed its task rather than for a join to be done in the calling function), we would add and modify the following program statements: [14]
[14] While not shown, we would also remove the lines of code that implement the join. Of course, if the initial thread (process) terminates before all threads have finished, complete output will not be generated.
. . . int main(int argc, char *argv[]) { pthread_t thread_id[MAX]; 20 int status, *p_status = &status; pthread_attr_t attr_obj ; // allocate attribute object setvbuf(stdout, (char *) NULL, _IONBF, 0); . . . cout << "Displaying" << endl; // Allocate & set atrib. obj pthread_attr_init( &attr_obj) ; pthread_attr_setdetachstate( &attr_obj, PTHREAD_CREATE_DETACHED ) ; for (int i = 0; i < argc-1; ++i) { // generate threads . . .
The set and get attribute calls return a 0 if they are successful. If they fail, they return EINVAL (22) if passed an invalid parameter or ENOTSUP (95) [15] if the parameter specifies an unsupported feature.
[15] Linux does not support the constant ENOTSUP directly (which is usually assigned the value 48), but as a patch, defines ENOTSUP in terms of EOPNOTSUPP.