Говорят, что вы должны только вызывать функции асинхронно внутри обработчика сигнала. Мой вопрос: что означает асинхронная безопасность? Я думаю, что функция, которая является как реентерабельной, так и потоковой безопасностью, асинхронно-безопасна. Или Нет?
Что представляет собой асинхронная безопасность
Ответ 1
Повторный вход и безопасность потока имеют немного или ничего общего с этим. Побочные эффекты, состояние и прерывание этих функций - это факты, которые имеют значение.
асинхронно-безопасная функция [GNU Pth]
Функция асинхронна, или безопасным асинхронным сигналом, если его можно назвать безопасным и без побочные эффекты из контекста обработчика сигналов. То есть, это должно быть может быть прервана в любой точке для линейного выхода из последовательности без возникновения несогласованного состояния. Он должен также функционировать должным образом когда глобальные данные могут сами быть в противоречивом состоянии. Некоторые асинхронно-безопасные операции перечислены здесь:
- вызов функции
signal()
для переустановки обработчика сигнала- безоговорочно изменить переменную
volatile sig_atomic_t
(as модификация этого типа является атомной)- вызов функции
_Exit()
для немедленно прекратить выполнение программы- вызывать асинхронный функции, как указано в вашей реализации
Несколько функций портативно асинхронно-безопасный. Если функция выполняет любые другие функции операций, он, вероятно, не является асинхронно безопасным.
Эмпирическое правило - это только сигнал некоторой переменной условия из обработчика сигнала (например, условие futex/pthread, цикл epoll для пробуждения и т.д.).
UPDATE:
Как сказал посол в России, даже вызов pthread_cond_signal
- плохая идея. Я проверил исходный код недавнего eglibc
, и там есть пара блокировки/разблокировки. Таким образом, введение возможности для тупика. Это оставляет нам несколько опций для сигнализации других потоков:
- Используя
eventfd
. - Изменение глобальной атомной переменной и надеемся, что SA_RESTART не установлен, а другие потоки будут проверять наш атом.
Ответ 2
Для вашего собственного кода да, повторный вход и потокобезопасность - это характеристики, которые вам нужны, так как в зависимости от того, как вы настраиваете механизм обработки сигнала, ваш обработчик сигнала сам может быть прерван другим сигналом. В общем, старайтесь делать как можно меньше работы внутри обработчика сигнала. Установка флагов для запуска специального кода в вашем обычном потоке программы - это, вероятно, все, что вам нужно делать.
Для функций в ОС, которые вы могли бы назвать, проверьте man 7 signal
список безопасных вызовов. Обратите внимание, что malloc()
и free()
в списке не. API-интерфейсы pthread-синхронизации также не входят в список, но я думаю, что некоторые из них должны быть безопасными для вызова, поэтому вы можете безопасно установить глобальный флаг в обработчике сигналов.