непустой, то значение, возвращаемое потоком (указатель на некоторый объект), хранится в ячейке памяти, на которую указывает
status
.
Функция pthread_self
Каждый поток снабжен идентификатором, уникальным в пределах данного процесса. Идентификатор потока возвращается функцией
pthread_create
и, как мы видели, используется функцией
pthread_join
. Поток может узнать свой собственный идентификатор с помощью вызова
pthread_self
.
#include <pthread.h>
pthread_t pthread_self(void);
Возвращает:
идентификатор вызывающего потока
Сравнивая потоки и процессы Unix, можно отметить, что функция
pthread_self
аналогична функции
getpid
.
Функция pthread_detach
Поток может быть либо присоединяемым( joinable), каким он является по умолчанию, либо отсоединенным( detached). Когда присоединяемый поток завершает свое выполнение, его статус завершения и идентификатор сохраняются, пока другой поток данного процесса не вызовет функцию
pthread_join
. В свою очередь, отсоединенный поток напоминает процесс-демон: когда он завершается, все занимаемые им ресурсы освобождаются и мы не можем отслеживать его завершение. Если один поток должен знать, когда завершится выполнение другого потока, нам следует оставить последний присоединяемым.
Функция
pthread_detach
изменяет состояние потока, превращая его из присоединяемого в отсоединенный.
#include <pthread.h>
int pthread_detach(pthread_t tid);
Возвращает: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки
Эта функция обычно вызывается потоком при необходимости изменить собственный статус в следующем формате:
pthread_detach(pthread_self);
Функция pthread_exit
Одним из способов завершения потока является вызов функции
pthread_exit
.
#include <pthread.h>
void pthread_exit(void * status);
Ничего не возвращает вызвавшему потоку
Если поток не является отсоединенным, идентификатор потока и статус завершения сохраняются до того момента, пока какой-либо другой поток данного процесса не вызовет функцию
pthread_join
.
Указатель
status
не должен указывать на объект, локальный по отношению к вызывающему потоку, так как этот объект будет уничтожен при завершении потока.
Существуют и другие способы завершения потока.
Функция, которая была вызвана потоком (третий аргумент функции
pthread_create
), может возвратить управление в вызывающий процесс. Поскольку, согласно своему объявлению, эта функция возвращает указатель
void
, возвращаемое ею значение играет роль статуса завершения данного потока.
Если функция
main
данного процесса возвращает управление или любой поток вызывает функцию
exit
, процесс завершается вместе со всеми своими потоками.
26.3. Использование потоков в функции str_cli
В качестве первого примера использования потоков мы перепишем нашу функцию
str_cli
. В листинге 16.6 была представлена версия
этой функции, в которой использовалась функция
fork
. Напомним, что были также представлены и некоторые другие версии этой функции: изначально в листинге 5.4 функция блокировалась в ожидании ответа и была, как мы показали, далека от оптимальной в случае пакетного ввода; в листинге 6.2 применяется блокируемый ввод-вывод и функция
select
; версии, показанные в листинге 16.1 и далее, используют неблокируемый ввод-вывод.
На рис. 26.1 показана структура очередной версии функции str_cli, на этот раз использующей потоки, а в листинге 26.1 [1] представлен код этой функции.
Рис. 26.1. Измененная функция str_cli, использующая потоки
Листинг 26.1. Функция str_cli, использующая потоки
//threads/strclithread.c
1 #include "unpthread.h"
2 void *copyto(void*);
1
Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.