The initial thread is special because Pthreads retains traditional UNIX process behavior when the function main returns; that is, the process terminates without allowing other threads to complete. In general, you do not want to do this in a threaded program, but sometimes it can be convenient. In many of the programs in this book, for example, threads are created that have no effect on anything outside the process. It doesn't really matter what those threads are doing, then, if the process goes away. When the process exits, those threads, all their states, and anything they might accomplish, simply 'evaporate'—there's no reason to clean up.

Detaching a thread that is still running doesn't affect the thread in any way—it just informs the system that the thread's resources can be reclaimed when the thread eventually terminates.

Although 'thread evaporation' is sometimes useful, most of the time your process will outlive the individual threads you create. To be sure that resources used by terminated threads are available to the process, you should always detach each thread you create when you're finished with it. Threads that have terminated but are not detached may retain virtual memory, including their stacks, as well as other system resources. Detaching a thread tells the system that you no longer need that thread, and allows the system to reclaim the resources it has allocated to the thread.

If you create a thread that you will never need to control, you can use an attribute to create the thread so that it is already detached. (We'll get to attributes later, in Section 5.2.3.) If you do not want to wait for a thread that you created, and you know that you will no longer need to control that thread, you can detach it at any time by calling pthread_detach. A thread may detach itself, or any other thread that knows its pthread_t identifier may detach it at any time. If you need to know a thread's return value, or if you need to know when a thread has completed, call pthread_join. The pthread_join function will block the caller until the thread you specify has terminated, and then, optionally, store the terminated thread's return value. Calling pthread_join detaches the specified thread automatically.

As we've seen, threads within a process can execute different instructions, using different stacks, all at the same time. Although the threads execute independently of each other, they always share the same address space and file

descriptors. The shared address space provides an important advantage of the threaded programming model by allowing threads to communicate efficiently.

Some programs may create threads that perform unrelated activities, but most often a set of threads works together toward a common goal. For example, one set of threads may form an assembly line in which each performs some specific task on a shared data stream and then passes the data on to the next thread. A set of threads may form a work crew and divide independent parts of a common task. Or one 'manager' thread may take control and divide work among a 'crew' of worker threads. You can combine these models in a variety of ways; for example, a work crew might perform some complicated step in a pipeline, such as transforming a slice of an array.

The following program, lifecycle.c, creates a thread. We'll refer to this simple example in the following sections about a thread's life cycle.

7-10 The thread function, thread_routine, returns a value to satisfy the standard thread function prototype. In this example the thread returns its argument, and the value is always NULL.

18-25 The program creates a thread by calling pthread_create, and then waits for it by calling pthread_join. You don't need to wait for a thread, but if you don't, you'll need to do something else to make sure the process runs until the thread completes. Returning from main will cause the process to terminate, along with all threads. You could, for example, code the main thread to terminate by calling pthread_exit, which would allow the process to continue until all threads have terminated.

26-29 When the join completes, the program checks the thread's return value, to be sure that the thread returned the value it was given. The program exits with 0 (success) if the value is NULL, or with 1 otherwise.

It is a good idea for all thread functions to return something, even if it is simply NULL. If you omit the return statement, pthread_join will still return some value—whatever happens to be in the place where the thread's start function would have stored a return value (probably a register).

¦ lifecycle.c

1 #include <pthread.h>

2 #include 'errors.h' 3

4 /*

5 * Thread start routine.

6 */

7 void *thread_routine (void *arg)

8 {

9 return arg; 10 }

11

12 main (int argc, char *argv[])

13 {

14 pthread_t thread_id;

15 void *thread result;

16 int status;

17

18 status = pthread_create (

19 &thread_id, NULL, thread_routine, NULL);

20 if (status != 0)

21  err_abort (status, 'Create thread');

22

23 status = pthread_join (thread_id, &thread_result);

24 if (status != 0)

25  err_abort (status, 'Join thread');

26 if (thread_result == NULL)

27  return 0;

28 else

29  return 1;

30 }

If the 'joining' thread doesn't care about the return value, or if it knows that the 'joinee' (the thread with which it is joining) didn't return a value, then it can pass NULL instead of &retval in the call to pthread_join. The joinee's return value will be ignored.

When the call to pthread_join returns, the joinee has been detached and you can't join with it again. In the rare cases where more than one thread might need to know when some particular thread has terminated, the threads should wait on a condition variable instead of calling pthread_join. The terminating thread would store its return value (or any other information) in some known location, and broadcast the condition variable to wake all threads that might be interested.

2.2 The life of a thread

Come, listen, my men, while I tell you again

The five unmistakable marks

By which you may know, wheresoever you go.

The warranted genuine Snarks.

Lewis Carroll, The Hunting of the Snark
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату