C/C++ Реентрабельность функций обработки сигналов
Итак, есть такое понятие, как реентрабельность функции.
При обработке сигналов в linux возникают проблемы.
Например, на SIGUSR1 я должен прочитать файл, и вызвать виртуальный метод, передав туда его содержимое.
void sigusr1_handler(int signum)
{
std::string msg = read_sigmsg(get_sigmsg_filename());
g_bootstraped->signal_handler(signum, msg); // виртуальный метод из глобального объекта
}
std::string является нереентрабельным, т.к. использует операторы new и delete, которые тоже нереентрабельные.
Я придумал три решения:
- Из обработчика сигнала запускать поток, в котором проделать вышеприведенные операции. Но у меня вопрос: решит ли это проблему реентрабельности? В теории должно, ведь реентрабельность - это про один и тот же поток. Но придется требовать от наследников моего класса потокобезопасности.
- Использовать отдельный поток, в котором через системный вызов
sigwait()обрабатывать сигналы по очереди. Но тут уже не гарантируется реалтайм. Но не придется требовать от наследников моего класса потокобезопасности. - Не передавать сообщения через сигналы, а использовать другой способ межпроцессного взаимодействия. Оно менее предпочтительное, в силу того, что хотелось бы единообразия, для зарезервированного моей системой сигнала, который вызывает перезагрузку процесса, получившего его.
Хотелось бы критики этих решений.
Ответы (1 шт):
Операторы new delete реентрабельные. Однако тут проблема посложнее, дело в том, что в обработчике асинхронных сигналов можно вызывать только функции из категории async-signal-safe, а не просто reentrant. Соответственно создание потоков в обработчике не допускается. не гарантируется реалтайм - он не гарантируется в любом случае.
Вариант 3 с полным отказом от сигналов выглядит предпочтительно. Чем меньше приходится иметь дело с этими атавизмами, тем лучше.