Ошибка опроса C ++ на любом сигнале

Мой обработчик сигналов для сигналов SIGTERM и SIGINT вызывает ошибку опроса при получении любого из них. Я не уверен, почему это происходит, и я думаю, что я не знаю о каком-то поведении, которое я пропустил.

while(!signalHandler.gotExitSignal()) {
switch (poll(&ufds[0], NUM_FDS, POLL_TIMEOUT)) {
case -1: {
throw std::runtime_error("poll error (-1)"); /* ABORT */
}
.
.

Мой signalHandler — это класс, который содержит обработку sigaction.

struct sigaction killAction, termAction;

memset(&killAction, 0, sizeof(struct sigaction));
killAction.sa_handler = SignalHandler::ExitHandler;
sigemptyset(&killAction.sa_mask);
killAction.sa_flags = 0;
if(sigaction(SIGTERM, &killAction, NULL) < 0)
throw SignalException("sigaction failed for killAction");

memset(&termAction, 0, sizeof(struct sigaction));
termAction.sa_handler = SignalHandler::ExitHandler;
sigemptyset(&termAction.sa_mask);
termAction.sa_flags = 0;
if(sigaction(SIGTERM, &termAction, NULL) < 0)
throw SignalException("sigaction failed for termAction");

Итак, мое ожидаемое поведение цикла фрагментов, которое я дал, должно быть:

  1. while (! signalHandler.gotExitSignal ()) {
  2. переключатель (опрос (&ufds [0], NUM_FDS, POLL_TIMEOUT)) {
  3. После опроса сделайте уборку
  4. Перейти к 1
  5. while (! signalHandler.gotExitSignal ()) {
  6. ПРЕРЫВАТЕЛЬ
  7. переключатель (опрос (&ufds [0], NUM_FDS, POLL_TIMEOUT)) {
  8. После опроса сделайте уборку
  9. Перейти к 1
  10. Разрыв цикла

Что происходит:

  1. while (! signalHandler.gotExitSignal ()) {
  2. переключатель (опрос (&ufds [0], NUM_FDS, POLL_TIMEOUT)) {
  3. После опроса сделайте уборку
  4. Перейти к 1
  5. while (! signalHandler.gotExitSignal ()) {
  6. ПРЕРЫВАТЕЛЬ
  7. throw std :: runtime_error («ошибка опроса (-1)»);

Я попробовал сценарий, в котором после переключения опроса я спал в течение 2 секунд, а затем завершил программу — она ​​изящно завершилась с условием цикла. Проблема существует, пока я опрашиваю, а затем получаю сигнал. Я не использую сигнал SIGHUP, который используется для сообщения программе о необходимости перезагрузить ее конфигурацию, но я установил сигнал для проверки SIGHUP, и он завершил мою программу с ошибкой опроса, как и другие мои сигналы. Но у меня не может произойти сбой моей программы при любом сигнале, мне интересно, что я что-то забыл.

0

Решение

Это ожидается. При блокировке в poll () и поступлении сигнала опрос не будет выполнен, и errno будет установлен на EINTR, Вы получите такое же поведение для большинства системных вызовов.

Вы можете и должны это обнаружить (теперь вы тоже выходите из цикла опроса, так как poll () вернется
когда сигнал пойман.)

while(!signalHandler.gotExitSignal()) {
switch (poll(&ufds[0], NUM_FDS, POLL_TIMEOUT)) {
case -1: {
if (errno == EINTR) {
continue;
}
throw std::runtime_error("poll error (-1)"); /* ABORT */
}

Скорее всего, вы хотите установить SA_RESTART флаг для подписи тоже.

 killAction.sa_flags = SA_RESTART;

Это приведет к тому, что большинство системных вызовов НЕ возвратят ошибку при обнаружении сигнала. Прочтите man-страницу для sigaction () для получения дополнительной информации и прочитайте раздел «Прерывание системных вызовов и библиотечных функций обработчиками сигналов» в человек 7 сигнал.

Примечательно, что poll () будет по-прежнему прерываться (немедленно возвращать ошибку) сигналом независимо от установки SA_RESTART флаг.

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]