37 */

38 #define err_abort(code,text) do {

39  fprintf (stderr, '%s at '%s':%d: %s ',

40  text, _FILE_, _LINE_, strerror (code));

41  abort ();

42 } while (0)

43 #define errno_abort(text) do {

44  fprintf (stderr, '%s at '%s':%d: %s ',

45  text, _FILE_, _LINE_, strerror (errno));

46  abort ( );

47 } while (0)

48

49 #endif

The one exception to the Pthreads error rules is pthread_getspecific, which returns the thread-specific data value of a shared 'key.' Section 5.4 describes thread-specific data in detail, but for now we're just concerned with error reporting. The capability of managing thread-specific data is critical to many applications, and the function has to be as fast as possible, so the pthread_ getspecific function doesn't report errors at all. If the pthread_key_t value is illegal, or if no value has been set in the thread, pthread_getspecific just returns the value NULL.

2 Threads

'lf seven maids with seven mops

Swept it for half a year.

Do you suppose,' the Walrus said,

'That they could get it clear?'

'I doubt it,' said the Carpenter,

And shed a bitter tear.

Lewis Carroll, Through the Looking-Glass

Threads are (and perhaps this will come as no surprise) the essential basis of the style of programming that I am advocating. Although this chapter focuses on threads, you will never learn everything you need to know about threads by simply skipping to this chapter and reading it. Threads are a critical part of the landscape, but you can't do much with only threads. Nevertheless, one must start somewhere, and here we are.

Section 2.1 describes the programming aspects of creating and managing threads in your program, that is, how to create threads, how they are represented in your program, and the most basic things you can do to them once you've created them.

Section 2.2 describes the life cycle of a thread, from creation through 'recycling,' taking you through all the scheduling states threads can assume along the way.

2.1 Creating and using threads

'A loaf of bread,' the Walrus said,

'Is what we chiefly need:

Pepper and vinegar besides

Are very good indeed—

ow, if you're ready, Oysters dear,

We can begin to feed.'

Lewis Carroll, Through the Looking-Glass

pthread_t thread;

int pthread_equal (pthread_t tl, pthread_t t2);

int pthread_create (pthread_t *thread,

const pthread_attr_t *attr,

void *(*start)(void *), void *arg);

pthread_t pthread_self (void);

int sched_yield (void);

int pthread_exit (void *value_ptr);

int pthread_detach (pthread_t thread);

int pthread_join (pthread_t thread, void **value_ptr);

The introduction covered some of the basics of what a thread is, and what it means to the computer hardware. This section begins where the introduction left off. It explains how a thread is represented in your program, what it means to your program, and some of the operations you can perform on threads. If you haven't read the introduction, this would be a good time to skip back to it. (I'll wait for you here.)

Within your program a thread is represented by a thread identifier, of the opaque type pthread_t. To create a thread, you must declare a variable of type pthread_t somewhere in your program. If the identifier is needed only within a function, or if the function won't return until the thread is done, you could declare the identifier with auto storage class. Most of the time, though, the identifier will be stored in a shared (static or extern) variable, or in a structure allocated from the heap.

A Pthreads thread begins by calling some function that you provide. This 'thread function' should expect a single argument of type void *, and should return a value of the same type. You create a thread by passing the thread function's address, and the argument value with which you want the function to be called, to pthread_create.

When you create a thread, pthread_create returns an identifier, in the pthread_t value referred to by the thread argument, by which your code refers to the new thread. A thread can also get its own identifier using the pthread_self function. There is no way to find a thread's identifier unless either the creator or the thread itself stores the identifier somewhere. You need to have a thread's identifier to do anything to the thread. If you'll need to know when a thread completes, for example, you must keep the identifier somewhere.

Pthreads provides the pthread_equal function to compare two thread identifiers. You can only test for equality. It doesn't make any sense to ask whether one thread identifier is 'greater than' or 'less than' another, because there is no ordering between threads. The pthread_equal function returns a nonzero value if the thread identifiers refer to the same thread, and the value 0 if they do not refer to the same thread.

The initial thread (main) is special.

When a C program runs, it begins in a special function named main. In a threaded program, this special stream of execution is called the 'initial thread' or sometimes the 'main thread.' You can do anything within the initial thread that you can do within any other thread. It can determine its own thread identifier by calling pthread_self, for example, or terminate itself by calling pthread_exit. If the initial thread stores its thread identifier somewhere accessible to another thread, that thread can wait for the initial thread to terminate, or detach the initial thread.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

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

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