Creating threads

Thread creation differs from process creation in that no parent-child relation exists between threads.

All threads, except the initial thread automatically created when a process is created, are on the same hierarchical level. A thread does not maintain a list of created threads, nor does it know the thread that created it.

When creating a thread, an entry-point routine and an argument must be specified. Every thread has an entry-point routine with one argument. The same entry-point routine may be used by several threads.

A thread has attributes, which specify the characteristics of the thread. To control thread attributes, a thread attributes object must be defined before creating the thread.

Thread attributes Oobject

The thread attributes are stored in an opaque object, the thread attributes object, used when creating the thread. It contains several attributes, depending on the implementation of POSIX options. The object is accessed through a variable of type pthread_attr_t. In AIX®, the pthread_attr_t data type is a pointer to a structure; on other systems, it may be a structure or another data type.

Creating and destroying the thread attributes object

o

The thread attributes object is initialized to default values by the pthread_attr_init subroutine. The attributes are handled by subroutines. The thread attributes object is destroyed by the pthread_attr_destroy subroutine. This subroutine can release storage dynamically allocated by the pthread_attr_init subroutine, depending on the implementation of the threads library.

In the following example, a thread attributes object is created and initialized with default values, then used and finally destroyed:

pthread_attr_t attributes;
                /* the attributes object is created */
...
if (!pthread_attr_init(&attributes)) {
                /* the attributes object is initialized */
        ...
                /* using the attributes object */
        ...
        pthread_attr_destroy(&attributes);
                /* the attributes object is destroyed */
}

The same attributes object can be used to create several threads. It can also be modified between two thread creations. When the threads are created, the attributes object can be destroyed without affecting the threads created with it.

Detachstate attribute

The following attribute is always defined:

Detachstate
Specifies the detached state of a thread.

The value of the attribute is returned by the pthread_attr_getdetachstate subroutine; it can be set by the pthread_attr_setdetachstate subroutine. Possible values for this attributes are the following symbolic constants:

PTHREAD_CREATE_DETACHED
Specifies that the thread will be created in the detached state
PTHREAD_CREATE_JOINABLE
Specifies that the thread will be created in the joinable state

The default value is PTHREAD_CREATE_JOINABLE.

If you create a thread in the joinable state, you must call the pthread_join subroutine with the thread. Otherwise, you may run out of storage space when creating new threads, because each thread takes up a significant amount of memory. For more information on the pthread_join subroutine, see Calling the pthread_join Subroutine.

Other threads attributes

AIX also defines the following attributes, which are intended for advanced programs and may require special execution privilege to take effect. Most programs operate correctly with the default settings. The use of the following attributes is explained in Using the inheritsched Attribute.

Contention Scope
Specifies the contention scope of a thread
Inheritsched
Specifies the inheritance of scheduling properties of a thread
Schedparam
Specifies the scheduling parameters of a thread
Schedpolicy
Specifies the scheduling policy of a thread

The use of the following stack attributes is explained in Stack Attributes.

Stacksize
Specifies the size of the thread's stack
Stackaddr
Specifies the address of the thread's stack
Guardsize
Specifies the size of the guard area of the thread's stack

Creating a thread using the pthread_create subroutine

A thread is created by calling the pthread_create subroutine. This subroutine creates a new thread and makes it runnable.

Using the thread attributes object

When calling the pthread_create subroutine, you may specify a thread attributes object. If you specify a NULL pointer, the created thread will have the default attributes. Thus, the following code fragment:

pthread_t thread;
pthread_attr_t attr;
...
pthread_attr_init(&attr);
pthread_create(&thread, &attr, init_routine, NULL);
pthread_attr_destroy(&attr);
is equivalent to the following:
pthread_t thread;
...
pthread_create(&thread, NULL, init_routine, NULL);

Entry point routine

When calling the pthread_create subroutine, you must specify an entry-point routine. This routine, provided by your program, is similar to the main routine for the process. It is the first user routine executed by the new thread. When the thread returns from this routine, the thread is automatically terminated.

The entry-point routine has one parameter, a void pointer, specified when calling the pthread_create subroutine. You may specify a pointer to some data, such as a string or a structure. The creating thread (the one calling the pthread_create subroutine) and the created thread must agree upon the actual type of this pointer.

The entry-point routine returns a void pointer. After the thread termination, this pointer is stored by the threads library unless the thread is detached. For more information about using this pointer, see Returning Information from a Thread.

Returned information

The pthread_create subroutine returns the thread ID of the new thread. The caller can use this thread ID to perform various operations on the thread.

Depending on the scheduling parameters of both threads, the new thread may start running before the call to the pthread_create subroutine returns. It may even happen that, when the pthread_create subroutine returns, the new thread has already terminated. The thread ID returned by the pthread_create subroutine through the thread parameter is then already invalid. It is, therefore, important to check for the ESRCH error code returned by threads library subroutines using a thread ID as a parameter.

If the pthread_create subroutine is unsuccessful, no new thread is created, the thread ID in the thread parameter is invalid, and the appropriate error code is returned. For more information, see Example of a Multi-Threaded Program.

Handling Thread IDs

The thread ID of a newly created thread is returned to the creating thread through the thread parameter. The current thread ID is returned by the pthread_self subroutine.

A thread ID is an opaque object; its type is pthread_t. In AIX, the pthread_t data type is an integer. On other systems, it may be a structure, a pointer, or any other data type.

To enhance the portability of programs using the threads library, the thread ID should always be handled as an opaque object. For this reason, thread IDs should be compared using the pthread_equal subroutine. Never use the C equality operator (==), because the pthread_t data type may be neither an arithmetic type nor a pointer.