Мы должны указать идентификатор потока, завершения которого ожидаем. К сожалению, невозможно задать режим ожидания завершения нескольких потоков (аналога waitpid с идентификатором процесса –1 нет).
Если указатель
У каждого потока имеется свой идентификатор, уникальный в пределах данного процесса. Идентификатор возвращается pthread_create и используется при вызове pthread_join. Поток может узнать свой собственный идентификатор вызовом pthread_self:
#include
pthread_t pthread_self(void);
/* Возвращает идентификатор вызвавшего потока */
Вызов pthread_self является аналогом getpid для процессов Unix.
Поток может являться как присоединяемым (по умолчанию), так и отсоединенным. При завершении присоединяемого потока его идентификатор и статус завершения сохраняются до тех пор, пока какой-либо другой поток данного процесса не вызовет pthread_join. Отсоединенный поток функционирует аналогично процессу-демону. После его завершения все ресурсы освобождаются. Никакой другой поток не может ожидать его завершения. Если имеется необходимость ожидания одним потоком завершения другого, лучше оставить последний присоединяемым.
Функция pthread_detach делает данный поток отсоединенным:
#include
int pthread_detach(pthread_t
/* Возвращает 0 в случае успешного завершения, положительное значение Еххх в случае ошибки */
Эта функция вызывается потоком при необходимости изменить собственный статус в форме
pthread_detach(pthread_self());
Одним из способов завершения потока является вызов pthread_exit:
#include
void pthread_exit(void
/* ничего не возвращает вызвавшему потоку */
Если поток не является отсоединенным, его идентификатор и статус завершения сохраняются для возвращения другому потоку, который может вызвать pthread_join.
Указатель
Поток может быть завершен двумя другими способами:
■ начальная функция потока (третий аргумент pthread_create) может вызвать return. Поскольку эта функция должна объявляться как возвращающая указатель на тип void, это возвращаемое значение становится статусом завершения потока;
■ функция main процесса может завершить работу или один из потоков может вызвать exit или _exit. При этом процесс завершает работу немедленно, вместе со всеми своими потоками.
ПРИЛОЖЕНИЕ В
Вспомогательные исходные коды
В.1. Заголовочный файл unpipc.h
Почти все программы книги подключают заголовочный файл unpipc.h, приведенный в листинге В.1.[1] Он подключает все стандартные системные заголовки, нужные большинству пpoгрaмм для работы с сетью, вместе с некоторыми общими системными заголовками. Он также определяет константы типа MAXLINE и прототипы функций ANSI С для функций, определенных в тексте (типа px_ipc_name), и для всех используемых в книге оберток. Мы не приводим эти прототипы.
//lib/unpipc.h
1 /* Наш заголовочный файл. */
2 #ifndef __unpipc_h
3 #define __unpipc_h
4 #include "../config.h" /* параметры конфигурации ОС */
5 /* "../config.h" создается сценарием configure */
6 /* изменяя список директив #include, нужно изменять файлы
7 ../aclocal.m4 и ../configure.in. чтобы работал сценарий configure */
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include
18 #include
19 #include
20 #include
21 #ifdef HAVE_MQUEUE_H
22 #include