О чем нужно заботиться при наличии сигналов - PullRequest
0 голосов
/ 21 декабря 2011

Я видел, что семафоры в моем приложении не всегда работали должным образом .Затем мне сказали, что это неожиданное поведение может быть вызвано тем, что сигнал прерывает вызов sem_wait.

Итак, мой вопрос в том, какую осторожность нужно соблюдать программисту при наличии сигналов.Для sem_wait мы можем проверить возвращаемые значения, но одинаково ли это для всех неасинхронных безопасных функций?И что еще мы должны помнить, ожидая, что сигналы прервут наш код?

1 Ответ

2 голосов
/ 21 декабря 2011

Сигналы UNIX - это червячная банка, просто чтобы сказать это.

Есть 2 лагеря в отношении системных вызовов и сигналов.

  • Семантика SysV / Posix: системные вызовы прерываютсясигнал, они возвращают ошибку и устанавливают errno в EINTR
  • . Системные вызовы семантики BSD автоматически перезапускаются при возникновении сигнала (ну, большинство из них в любом случае, а некоторые нет, например, select / poll / sleep).

При использовании signal () по умолчанию используется одно из двух выше: в системах BSD и Linux по умолчанию используется семантика BSD, а у каждого [нужного цитирования] есть семантика SysV.(В Linux это зависит от многих вещей, например, компиляция с -std = c99 дает семантику SysV, с -std = gnu99 дает семантику BSD. См., Например, http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html)

Когда вы устанавливаете обработчик сигнала с sigaction (), вы можете выбрать семантику с флагами SA_RESTART.

В основном:

  • Не используйте сигналы, если можете помочь.
  • Используйте BSDсемантика, если вы можете.
  • В коде, который должен быть переносимым и обрабатывать сигналы, вам нужно обернуть каждый системный вызов в цикл, который проверяет вызов на сбой, проверяет errno на EINTR и снова выполняет системный вызов(или сделать что-то на основе перехваченного сигнала).
  • библиотечные вызовы могут использовать сигналы, даже если ваш код этого не делает. Системные вызовы
  • в целом, с семантикой SysV / Posix, вернутся -1 и установите для errno значение EINTR. Но прочитайте документацию, чтобы узнать, что это за состояние ошибки.

РЕДАКТИРОВАТЬ: отредактировано, поскольку я перепутал семантику BSD против Sysv.

...