[ Team LiB ] |
26.2 Basic Thread Functions: Creation and TerminationIn this section, we will cover five basic thread functions and then use these in the next two sections to recode our TCP client/server using threads instead of fork. pthread_create FunctionWhen a program is started by exec, a single thread is created, called the initial thread or main thread. Additional threads are created by pthread_create.
Each thread within a process is identified by a thread ID, whose datatype is pthread_t (often an unsigned int). On successful creation of a new thread, its ID is returned through the pointer tid. Each thread has numerous attributes: its priority, its initial stack size, whether it should be a daemon thread or not, and so on. When a thread is created, we can specify these attributes by initializing a pthread_attr_t variable that overrides the default. We normally take the default, in which case, we specify the attr argument as a null pointer. Finally, when we create a thread, we specify a function for it to execute. The thread starts by calling this function and then terminates either explicitly (by calling pthread_exit) or implicitly (by letting the function return). The address of the function is specified as the func argument, and this function is called with a single pointer argument, arg. If we need multiple arguments to the function, we must package them into a structure and then pass the address of this structure as the single argument to the start function. Notice the declarations of func and arg. The function takes one argument, a generic pointer (void *), and returns a generic pointer (void *). This lets us pass one pointer (to anything we want) to the thread, and lets the thread return one pointer (again, to anything we want). The return value from the Pthread functions is normally 0 if successful or nonzero on an error. But unlike the socket functions, and most system calls, which return –1 on an error and set errno to a positive value, the Pthread functions return the positive error indication as the function's return value. For example, if pthread_create cannot create a new thread because of exceeding some system limit on the number of threads, the function return value is EAGAIN. The Pthread functions do not set errno. The convention of 0 for success or nonzero for an error is fine since all the Exxx values in <sys/errno.h> are positive. A value of 0 is never assigned to one of the Exxx names. pthread_join FunctionWe can wait for a given thread to terminate by calling pthread_join. Comparing threads to Unix processes, pthread_create is similar to fork, and pthread_join is similar to waitpid.
We must specify the tid of the thread that we want to wait for. Unfortunately, there is no way to wait for any of our threads (similar to waitpid with a process ID argument of –1). We will return to this problem when we discuss Figure 26.14. If the status pointer is non-null, the return value from the thread (a pointer to some object) is stored in the location pointed to by status. pthread_self FunctionEach thread has an ID that identifies it within a given process. The thread ID is returned by pthread_create and we saw it was used by pthread_join. A thread fetches this value for itself using pthread_self.
Comparing threads to Unix processes, pthread_self is similar to getpid. pthread_detach FunctionA thread is either joinable (the default) or detached. When a joinable thread terminates, its thread ID and exit status are retained until another thread calls pthread_join. But a detached thread is like a daemon process: When it terminates, all its resources are released and we cannot wait for it to terminate. If one thread needs to know when another thread terminates, it is best to leave the thread as joinable. The pthread_detach function changes the specified thread so that it is detached.
This function is commonly called by the thread that wants to detach itself, as in pthread_detach (pthread_self()); pthread_exit FunctionOne way for a thread to terminate is to call pthread_exit.
If the thread is not detached, its thread ID and exit status are retained for a later pthread_join by some other thread in the calling process. The pointer status must not point to an object that is local to the calling thread since that object disappears when the thread terminates. There are two other ways for a thread to terminate:
|
[ Team LiB ] |