Мы можем приостановить выполнение текущего потока и ждать завершения выполнения какого-либо другого потока, используя функцию pthread_join
. Сравнивая потоки и процессы Unix, можно сказать, что функция pthread_create
аналогична функции fork
, а функция pthread_join
— функции waitpid
.
#include
int pthread_join(pthread_t tid , void ** status );
Возвращает: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки
Следует указать идентификатор tid
того потока, завершения которого мы ждем. К сожалению, нет способа указать, что мы ждем завершения любого потока данного процесса (тогда как при работе с процессами мы могли с помощью функции waitpid
ждать завершения любого процесса, задав аргумент идентификатора процесса, равный -1). Мы вернемся к этой проблеме при обсуждении листинга 26.11.
Если указатель status
непустой, то значение, возвращаемое потоком (указатель на некоторый объект), хранится в ячейке памяти, на которую указывает status
.
Каждый поток снабжен идентификатором, уникальным в пределах данного процесса. Идентификатор потока возвращается функцией pthread_create
и, как мы видели, используется функцией pthread_join
. Поток может узнать свой собственный идентификатор с помощью вызова pthread_self
.
#include
pthread_t pthread_self(void);
Возвращает: идентификатор вызывающего потока
Сравнивая потоки и процессы Unix, можно отметить, что функция pthread_self
аналогична функции getpid
.
Поток может быть либо присоединяемым ( joinable ), каким он является по умолчанию, либо отсоединенным ( detached ). Когда присоединяемый поток завершает свое выполнение, его статус завершения и идентификатор сохраняются, пока другой поток данного процесса не вызовет функцию pthread_join
. В свою очередь, отсоединенный поток напоминает процесс-демон: когда он завершается, все занимаемые им ресурсы освобождаются и мы не можем отслеживать его завершение. Если один поток должен знать, когда завершится выполнение другого потока, нам следует оставить последний присоединяемым.
Функция pthread_detach
изменяет состояние потока, превращая его из присоединяемого в отсоединенный.
#include
int pthread_detach(pthread_t tid );
Возвращает: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки
Эта функция обычно вызывается потоком при необходимости изменить собственный статус в следующем формате:
pthread_detach(pthread_self());
Одним из способов завершения потока является вызов функции pthread_exit
.
#include
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] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
представлен код этой функции.
Читать дальше
Конец ознакомительного отрывка
Купить книгу