Литмир - Электронная Библиотека
Содержание  
A
A

<i>Возвращает: 0 в случае успешного выполнения, положительное значение Exxx в случае ошибки</i>

Эта функция обычно вызывается потоком при необходимости изменить собственный статус в следующем формате:

pthread_detach(pthread_self());

Функция pthread_exit

Одним из способов завершения потока является вызов функции

pthread_exit
.

#include &lt;pthread.h&gt;

void pthread_exit(void *<i>status</i>);

<i>Ничего не возвращает вызвавшему потоку</i>

Если поток не является отсоединенным, идентификатор потока и статус завершения сохраняются до того момента, пока какой-либо другой поток данного процесса не вызовет функцию

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] представлен код этой функции.

UNIX: разработка сетевых приложений - img_133.png

Рис. 26.1. Измененная функция str_cli, использующая потоки

Листинг 26.1. Функция str_cli, использующая потоки

//threads/strclithread.c

 1 #include &quot;unpthread.h&quot;

 2 void *copyto(void*);

 3 static int sockfd; /* глобальная переменная, доступная обоим потокам */

 4 static FILE *fp;

 5 void

 6 str_cli(FILE *fp_arg, int sockfd_arg)

 7 {

 8  char recvline[MAXLINE];

 9  pthread_t tid;

10  sockfd = sockfd_arg; /* копирование аргументов во внешние переменные */

11  fp = fp_arg;

12  Pthread_create(&amp;tid, NULL, copyto, NULL);

13  while (Readline(sockfd, recvline. MAXLINE) &gt; 0)

14   Fputs(recvline, stdout);

15 }

16 void*

17 copyto(void *arg)

18 {

19  char sendline[MAXLINE];

20  while (Fgets(sendline, MAXLINE, fp) != NULL)

21   Writen(sockfd, sendline, strlen(sendline));

22  Shutdown(sockfd, SHUT_WR); /* признак конца файла в стандартном

                                  потоке ввода, отправка сегмента FIN */

23  return (NULL);

24  /* завершение потока происходит, когда в стандартном потоке ввода

       встречается признак конца файла */

25 }

Заголовочный файл unpthread.h

1
Мы впервые встречаемся с заголовочным файлом
unpthread.h
. Он включает наш обычный заголовочный файл
unp.h
, затем — заголовочный файл POSIX
&lt;pthread.h&gt;
, и далее определяет прототипы наших потоковых функций-оберток для
pthread_XXX
(см. раздел 1.4), название каждой из которых начинается с
Pthread_
.

Сохранение аргументов во внешних переменных

10-11
 Для потока, который мы собираемся создать, требуются значения двух аргументов функции
str_cli
:
fp
 — указатель на структуру
FILE
для входного файла, и
sockfd
— сокет TCP, связанный с сервером. Для простоты мы храним эти два значения во внешних переменных. Альтернативой является запись этих двух значений в структуру, указатель на которую затем передается в качестве аргумента создаваемому потоку.

Создание нового потока

12
 Создается поток, и значение нового идентификатора потока сохраняется в
tid
. Функция, выполняемая новым потоком, — это
copyto
. Никакие аргументы потоку не передаются.

Главный цикл потока: копирование из сокета в стандартный поток вывода

13-14
 В основном цикле вызываются функции
readline
и
fputs
, которые осуществляют копирование из сокета в стандартный поток вывода.

Завершение

15
 Когда функция
str_cli
возвращает управление, функция main завершается при помощи вызова функции
exit
(см. раздел 5.4). При этом завершаются все потоки данного процесса. В обычном сценарии второй поток уже должен завершиться в результате считывания признака конца файла из стандартного потока ввода. Но в случае, когда сервер преждевременно завершил свою работу (см. раздел 5.12), при вызове функции
exit
завершается также и второй поток, чего мы и добиваемся.

вернуться

1

Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.

282
{"b":"225366","o":1}