Boost Семафоры под Linux и EINTR код возврата

64
10

В boost (я использую 1.54.0) я вижу реализацию для posix semaphore wait:

inline void semaphore_wait(sem_t *handle)
{
int ret = sem_wait(handle);
if(ret != 0){
throw interprocess_exception(system_error_code());
}
}

Руководство по posix semaphore говорит:

ОШИБКИ

  EINTR  The call was interrupted by a signal handler; see signal(7).

Правильно ли, что форсировать исключение семафорного броска, если я отправлю убийцу в ожидающий поток? Если да, то как вы справляетесь с этой ситуацией?

спросил(а) 2021-01-19T14:17:07+03:00 6 месяцев, 1 неделя назад
1
Решение
101

По-моему, это, вероятно, ошибка в Boost.Interprocess. Пожалуйста, сообщите об этом разработчикам, по крайней мере, они смогут дать обоснование, если это намеренно.

Комментирование предложения по управлению сигналами в комментариях выше. Верно, что типичное многопоточное приложение должно маскировать сигналы, которые не предназначены для обработки потоками, оставляя только один поток для обработки сигналов. Однако это не обязательное правило.

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

Во-вторых, некоторые сигналы могут быть намеренно оставлены без маски, чтобы улавливать события, связанные с этим конкретным потоком. Например, можно зарегистрировать обработчик для SIGSEGV для обнаружения ошибок сегментации. Этот обработчик будет вызван в оскорбительном потоке, и приложение может теоретически справиться с ошибкой. Аналогично, SIGUSR1 или SIGUSR2 могут использоваться для сигнализации событий, определенных приложением, для конкретных потоков.

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

ответил(а) 2021-01-19T14:17:07+03:00 6 месяцев, 1 неделя назад
45

Реализация выглядит нормально. Можно использовать флаг SA_RESTART, чтобы вызов автоматически перезапускался. http://man7.org/linux/man-pages/man7/signal.7.html

ответил(а) 2021-01-19T14:17:07+03:00 6 месяцев, 1 неделя назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема