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

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

В листинге 14.1[1] показана наша функция connect_timeo, вызывающая функцию connect с ограничением по времени, заданным вызывающим процессом. Первые три аргумента — это аргументы, которых требует функция connect, а четвертый — это длительность ожидания в секундах.

Листинг 14.1. Функция connect с тайм-аутом

//lib/connect_timeo.c

 1 #include "unp.h"

 2 static void connect_alarm(int);

 3 int

 4 connect_timeo(int sockfd, const SA *saptr, socklen_t salen, int nsec)

 5 {

 6  Sigfunc *sigfunc;

 7  int n;

 8  sigfunc = Signal(SIGALRM, connect_alarm);

 9  if (alarm(nsec) != 0)

10   err_msg("connect_timeo: alarm was already set");

11  if ((n = connect(sockfd, saptr, salen)) < 0) {

12   close(sockfd);

13   if (errno == EINTR)

14    errno = ETIMEDOUT;

15  }

16  alarm(0); /* отключение alarm */

17  Signal(SIGALRM, sigfunc); /* восстанавливаем прежний обработчик

                                 сигнала */

18  return (n);

19 }

20 static void

21 connect_alarm(int signo)

22 {

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

24 }

Установка обработчика сигналов

8 Для SIGALRM устанавливается обработчик сигнала. Текущий обработчик сигнала (если таковой имеется) сохраняется, и таким образом мы можем восстановить его в конце функции.

Установка таймера

9-10 Таймер для процесса устанавливается на время (число секунд), заданное вызывающим процессом. Возвращаемое значение функции alarm — это число секунд, остающихся в таймере для процесса (если он уже установлен для процесса) в настоящий момент или 0 (если таймер не был установлен прежде). В первом случае мы выводим сообщение с предупреждением, поскольку мы стираем предыдущую установку таймера (см. упражнение 14.2).

Вызов функции connect

11-15 Вызывается функция connect, и если функция прерывается (EINTR), мы присваиваем переменной errno значение ETIMEDOUT. Сокет закрывается, чтобы не допустить продолжения трехэтапного рукопожатия.

Выключение таймера и восстановление предыдущего обработчика сигнала

16-18 Таймер при обнулении выключается, и восстанавливается предыдущий обработчик сигналов (если таковой имеется).

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

20-24 Обработчик сигнала просто возвращает управление. Предполагается, что это прервет ожидание функции connect, заставив ее возвратить ошибку EINTR. Вспомните нашу функцию signal (см. листинг 5.5), которая не устанавливает флага SA_RESTART, когда перехватываемый сигнал — это сигнал SIGALRM.

Одним из важных моментов в этом примере является то, что мы всегда можем сократить период ожидания для функции connect, используя эту технологию, но мы не можем увеличить период, заданный для ядра. В Беркли-ядре тайм-аут для функции connect обычно равен 75 с. Мы можем задать меньшее значение для нашей функции, допустим 10, но если мы задаем большее значение, скажем 80, тайм- аут самой функции connect все равно составит 75 с.

Другой важный момент в данном примере — то, что мы используем возможность прерывания системного вызова (connect) для того, чтобы возвратить управление, прежде чем истечет время ожидания ядра. Такой подход допустим, когда мы выполняем системный вызов и можем обработать возвращение ошибки EINTR. Но в разделе 29.7 мы встретимся с библиотечной функцией, выполняющей системный вызов, которая сама выполняет заново системный вызов при возвращении ошибки EINTR. Мы можем продолжать работать с сигналом SIGALRM и в этом случае, но в листинге 29.6 мы увидим, что нам придется воспользоваться функциями sigsetjmp и siglongjmp, поскольку библиотечная функция игнорирует ошибку EINTR.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

13.9.1 Сигнал синхронизации

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

13.9.1 Сигнал синхронизации Для некоторых функций (например, Interrupt Process) включение команды в общий поток данных не приводит к нужным результатам. Когда реальный терминал посылает сигнал прерывания, хост операционной системы получает этот сигнал сразу и быстро останавливает


12.3. Отношение сигнал-шум

Из книги Визуальное моделирование электронных схем в PSPICE автора Хайнеманн Роберт

12.3. Отношение сигнал-шум Следующее, что нам предстоит определить, - отношение сигнал/шум при выходной мощности 1 Вт и сопротивлении нагрузки 8 Ом. Для этого амплитуда выходного напряжения должна составлять 4 В, что соответствует амплитуде входного напряжения, равной


Оператор CONNECT

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен


Сигнал, импульс или поток?

Из книги Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform автора Кёртен Роб

Сигнал, импульс или поток? Оставим пока на время варианты CLOCK_SOFTTIME и CLOCK_MONOTONIC, поскольку они еще пока (на момент написания книги — прим. ред.) не реализованы. Втором параметром является указатель на структуру struct sigevent. Эта структура применяется для того, чтобы сообщить ядру


4.3. Функция connect

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

4.3. Функция connect Функция connect используется клиентом TCP для установления соединения с сервером TCP.#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);Возвращает: 0 в случае успешного выполнения функции, -1 в случае ошибкиАргумент sockfd — это дескриптор сокета,


5.13. Сигнал SIGPIPE

Из книги Идеальный программист. Как стать профессионалом разработки ПО автора Мартин Роберт С.

5.13. Сигнал SIGPIPE Что происходит, если клиент игнорирует возвращение ошибки из функции readline и отсылает следующие данные серверу? Это может произойти, если, например, клиенту нужно выполнить две операции по отправке данных серверу перед считыванием данных от него, причем


8.11. Функция connect для UDP

Из книги автора

8.11. Функция connect для UDP В конце разделе 8.9 мы упомянули, что асинхронные ошибки не возвращаются на сокете UDP, если сокет не был присоединен. На самом деле мы можем вызвать функцию connect для сокета UDP (см. раздел 4.3). Но это не приведет ни к чему похожему на соединение TCP: здесь не


Многократный вызов функции connect для сокета UDP

Из книги автора

Многократный вызов функции connect для сокета UDP Процесс с присоединенным сокетом UDP может снова вызвать функцию connect Для этого сокета, чтобы:? задать новый IP-адрес и порт;? отсоединить сокет.Первый случай, задание нового собеседника для присоединенного сокета UDP, отличается


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

Из книги автора

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


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

Из книги автора

Тайм-аут для функции recvfrom (функция select) Мы демонстрируем вторую технологию для установки тайм-аута (использование функции select) в листинге 14.3. Здесь показана наша функция readable_timeo, которая ждет, когда дескриптор станет готов для чтения, но не более заданного числа


Тайм-аут для функции recvfrom (параметр сокета SO_RCVTIMEO)

Из книги автора

Тайм-аут для функции recvfrom (параметр сокета SO_RCVTIMEO) В нашем последнем примере демонстрируется применение параметра сокета SO_RCVTIMEO. Мы устанавливаем этот параметр один раз для дескриптора, задавая значение тайм-аута, и этот тайм-аут затем применяется ко всем операциям


16.3. Неблокируемая функция connect

Из книги автора

16.3. Неблокируемая функция connect Когда сокет TCP устанавливается как неблокируемый, а затем вызывается функция connect, она немедленно возвращает ошибку EINPROGRESS, однако трехэтапное рукопожатие TCP продолжается. Далее мы с помощью функции select проверяем, успешно или нет завершилось


Прерванная функция connect

Из книги автора

Прерванная функция connect Что происходит, если наш вызов функции connect на обычном блокируемом сокете прерывается, скажем, перехваченным сигналом, прежде чем завершится трехэтапное рукопожатие TCP? Если предположить, что функция connect не перезапускается автоматически, то она


Сигнал SIGIO и сокеты UDP

Из книги автора

Сигнал SIGIO и сокеты UDP Использовать ввод-вывод, управляемый сигналом, с сокетами UDP довольно легко. Сигнал генерируется в следующих случаях:? на сокет прибывает дейтаграмма;? на сокете возникает асинхронная ошибка.Таким образом, когда мы перехватываем сигнал SIGIO для


Сигнал SIGIO и сокеты TCP

Из книги автора

Сигнал SIGIO и сокеты TCP К сожалению, использовать управляемый сигналом ввод-вывод для сокетов TCP почти бесполезно. Проблема состоит в том, что сигнал генерируется слишком часто, а само по себе возникновение сигнала не позволяет выяснить, что произошло. Как отмечается в [128, с.


Стоп-сигнал

Из книги автора

Стоп-сигнал Очень важно, чтобы тесты непрерывной интеграции все время проходили успешно. Они никогда не должны завершаться отказом. В случае отказа вся группа прекращает заниматься текущими делами и направляет все усилия на то, чтобы обеспечить успешное прохождение