Параллельное и распределенное программирование на С++ (Хьюз, Хьюз) - страница 428

Функция pthread_join () может завершиться неудачно, если:

[EDEADLK]  была обнаружена взаимоблокировка или значение параметра thread соответствует вызывающему потоку.

Функция pthread_join () не возвращает код ошибки [EINTR].

Примеры

Ниже приведен пример создания потока и его удаления.

>typedef struct {

> int *ar;

> long n;

>} subarray;

>void *incer (void *arg) {

> long i;

> for (i = О; i < ((subarray *)arg) ->n; i++) ((subarray *) arg) ->ar[i]++;

>}

>int main (void) {

>int ar[1000000];

>pthread_t th1, th2;

>subarray sbl, sb2;

>sbl.ar = &ar[О];

>sbl.n = 500000;

>(void) pthread_create(&thl, NULL, incer, &sbl);

>sb2.ar = &ar[500000];

>sb2.n = 500000;

>(void) pthread_create(&th2, NULL, incer, &sb2);

>(void) pthread_join(thl, NULL);

>(void) pthread_join(th2, NULL);

>return 0;

>}

Замечания по использованию

Отсутствуют.

Логическое обоснование

Функция pthread_join() представляет собой удобное и полезное средство для использования в многопоточных приложениях. Конечно, программист мог бы сымитировать эту функцию, если бы она не существовала, другими средствами, например, путем передачи функции start_routine () дополнительного состояния как части аргумента. Завершающийся поток в этом случае установил бы флаг, означающий завершение, и отправил бы условную переменную, которая является частью этого состояния, а присоединяющий поток ожидал бы получения этой условной переменной. Несмотря на то что такой метод позволил бы организовать ожидание наступления более сложных условий (например, завершения сразу нескольких потоков), ожидание завершения одного потока— весьма распространенная ситуация, и поэтому «заслуживает» отдельной функции. Кроме того, включение в библиотеку функции pthread_join () никоим образом не мешает программисту самому кодировать такие сложные ожидания. Таким образом, включение функции pthread_join () в этот том стандарта IEEE Std 1003.1-2001 считается весьма полезным.

Функция pthread_join() обеспечивает простой механизм, позволяющий приложению ожидать завершения потока. После того как поток завершится, приложение может приступать к освобождению ресурсов, которые использовались этим потоком.

Например, после возвращения функции pthread_join () может быть восстановлена любая область памяти, предоставленная приложением под стек.

Функции pthread_join () или pthread_detach () должны в конце концов быть вызваны для каждого потока, который создается с атрибутом detachstate, равным значению PTHREAD_CREATE_JOINABLE , чтобы м ожно было восстановить память, связанную с потоком.

Взаимодействие между функцией pthread_join () и механизмом отмены потока хорошо определено по следующим причинам: