Тайм-аут SIGALRM - Как это влияет на существующие операции? - PullRequest
0 голосов
/ 14 июля 2010

В настоящее время я использую select() в качестве таймера. У меня есть операции приема по сети, которые происходят внутри цикла, и каждые несколько секунд должна выполняться операция обработки.

В результате время ожидания оператора select () постоянно меняется - со временем уменьшается до нуля, а затем перезапускается с 3.

rv = select(selectmonitor+1, &readnet, NULL, NULL, &helper.timeout());

Когда что-то приходит в сеть, оператор повторяется, и значение, передаваемое ему helper.timeout (), уменьшается. В конце концов, значение будет либо равно нулю, либо система отключится, что приведет к выполнению функции обработки. Тем не менее, я заметил, что это достаточно ресурсоемкий - значение helper.timeout () должно постоянно вычисляться. Когда я пытаюсь получить несколько тысяч пакетов в секунду, время, необходимое для выполнения этой операции, приводит к потере пакетов.

Моя новая идея использует SIGALRM для решения этой проблемы. Это позволило бы мне установить таймер один раз, а затем реагировать, когда он выключен. Однако я не понимаю, как это повлияет на мою программу. Когда SIGALRM «выключается», он запускает функцию, которую я указываю. Однако как это прервет мой существующий код? И как только функция будет завершена, как возобновится мой существующий код (внутри оператора while)?

Кроме того, представляется невозможным установить сигнал SIGALRM для вызова функции внутри класса? Это правильно? Я полагаю, что могу вызвать функцию, которая, в свою очередь, может вызвать функцию внутри класса.

Спасибо за любую помощь заранее.

1 Ответ

1 голос
/ 14 июля 2010

Используйте ваш обработчик SIGALRM, чтобы установить переменную флага.

Используйте sigaction вместо signal для установки обработчика сигнала.Не устанавливайте флаг SA_RESTART.Если установлено SA_RESTART , а не , ваш оператор выбора будет прерван сигналом.Ваш выбор вернет -1, а errno будет EINTR.

Поскольку сигнал может произойти во время выполнения вашего другого кода, вы также захотите проверить переменную flag, вероятно, прямо перед входом в select.

Мне только что напомнили, что этот шаблон может привести к потере сигнала, если это происходит сразу после проверки флага и непосредственно перед вводом выбора.

Чтобы избежать этого, вам нужно использовать sigprocmask дляперед входом в цикл while блокируйте сигнал SIGALRM.Тогда вы используете pselect вместо select.Если дать pselect маску сигнала с немаскированной SIGALRM, сигнал будет всегда прерываться во время выбора, а не происходить в любое другое время.

...