Тайм-аут для функции recvfrom (сигнал SIGALRM)

Тайм-аут для функции recvfrom (сигнал SIGALRM)

В листинге 14.2 показана новая версия функции dg_cli, приведенной в листинге 8.4, в которую добавлен вызов функции alarm для прерывания функции recvfrom при отсутствии ответа в течение 5 с.

Листинг 14.2. Функция dg_cli, в которой при установке тайм-аута для функции recvfrom используется функция alarm

//advio/dgclitimeo3.c

 1 #include "unp.h"

 2 static void signalrm(int);

 3 void

 4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)

 5 {

 6  int n;

 7  char sendline[MAXLINE], recvline[MAXLINE + 1];

 8  Signal(SIGALRM, signalrm);

 9  while (Fgets(sendline, MAXLINE, fp) != NULL) {

10   Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);

11   alarm(5);

12   if ((n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL)) < 0) {

13    if (errno == EINTR)

14     fprintf(stderr, "socket timeout ");

15    else

16     err_sys("recvfrom error");

17   } else {

18    alarm(0);

19    recvline[n] = 0; /* завершающий нуль */

20    Fputs(recvline, stdout);

21   }

22  }

23 }

24 static void

25 sig_alrm(int signo)

26 {

27  return; /* просто прерываем recvfrom() */

28 }

Обработка тайм-аута из функции recvfrom

8-22 Мы устанавливаем обработчик для сигнала SIGALRM и затем вызываем функцию alarm для 5-секундного тайм-аута при каждом вызове функции recvfrom. Если функция recvfrom прерывается нашим обработчиком сигнала, мы выводим сообщение об ошибке и продолжаем работу. Если получена строка от сервера, мы отключаем функцию alarm и выводим ответ.

Обработчик сигнала SIGALRM

24-28 Наш обработчик сигналов возвращает управление, прерывая блокированную функцию recvfrom.

Этот пример работает корректно, потому что каждый раз, когда мы устанавливаем функцию alarm, мы читаем только один ответ. В разделе 20.4 мы попытаемся использовать ту же технологию, но поскольку мы будем считывать множество ответов для данной функции alarm, возникнет ситуация гонок, которую нам придется разрешить.

Данный текст является ознакомительным фрагментом.