функция обработчика сигнала в многопоточной среде

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

обрабатывается ли сигнал на уровне процесса или потока (могу ли я иметь специфичные для потока обработчики сигналов)?в каком контексте потока выполняется функция signal_handler?Можно ли отправить много сигналов SIGTERM за короткое время?имеет ли смысл использовать мьютекс для предотвращения параллельного выполнения signal_handler?
void signal_handler(int sig)
{
        switch (sig)
        {
        case SIGTERM:
            ::wxLogMessage(wxT("SIGTERM signal received ..."));
            break;
        case SIGINT:
            ::wxLogMessage(wxT("SIGINT signal received ..."));
            break;
        case SIGUSR1:
            ::wxLogMessage(wxT("SIGUSR1 signal received ..."));
            break;
        default:
            ::wxLogMessage(wxT("Unknown signal received ..."));
        }

        // send wxCloseEvent to main application window
        ::wxGetApp().GetTopWindow()->Close(true);
}

Я регистрирую обработчики сигналов в моей функции инициализации:

// register signal handlers
signal(SIGTERM, signal_handler);
signal(SIGINT,  signal_handler);
signal(SIGUSR1, signal_handler);

Ответы на вопрос(3)

Решение Вопроса

Будьте очень осторожны: какСигнал (7) страница говорит, только очень мало функций ("асинхронному сигнал безопасно» из них) могут (прямо или косвенно) вызываться внутри обработчиков сигналов. Связанные с мьютексом функции, вероятно, не должны вызываться в обработчиках сигналов. Смотрите такжеPthreads (7)

Вы могли бы рассмотреть возможность установкиvolatile sigatomic_t переменной в вашем обработчике сигналов, и время от времени проверяйте значение этого флага. Если у вас есть атомы C ++ 11 (или C11), например, C ++ 11станд :: атомное или C11Вы могли бы сделать этоvolatile переменная также атомная в этом смысле. Затем используйте средства атомной нагрузки, чтобы проверить это.

Документация Qt предлагаетследующий трюк: создатьтрубы (2) самостоятельно при запуске, а затем ваш обработчик сигналанаписать (2) (write syscall указан как безопасный для асинхронного сигнала) один (или более) байт [s] для канала к тому же процессу, и ваш цикл событий GUIОпрос (2) конец чтения этой трубы.

Linux-специфические способ обработки сигналов с помощью Qt может заключаться в использованииsignalfd (2) вероятно сQSocketNotifier (несмотря на название, он работает с дескрипторами файлов, которые могуттолько Розетки). С другими инструментами GUI вы, вероятно, также можете добавить дескриптор файла (один изsignalfd или жеpipe) быть опрошенным.

 Corvusoft07 мая 2017 г., 11:40
Обратите внимание на использование std :: atomic в обработчиках сигналовГарантировать реализации без блокировок. Посмотри пожалуйста:informit.com/articles/article.aspx?p=2204014

Этот ответ относится к потокам POSIX (pthreads).

Ссылаясь 1:

Сигналы могут обрабатываться на уровне потока, да. Если более одного потока процесса обрабатывает сигнал и сигнал отправляется процессу, но в конкретный поток не определяется, какой поток 'Обработчик s обработает сигнал. (увидетьman pthread_kill() для деталей)

Ссылаясь на 2:

Обработчик сигнала будет выполняться в контексте потока, который его установил. Это включает в себя основной поток.

Ссылаясь 3:

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

Ссылаясь на 4:

Если в игре задействованы общие ресурсы: да, по крайней мере для частей обработчиков код доступа к этим ресурсам одновременно. Более того, это также зависит от логики, которую вы пытаетесь реализовать.

Обработчики сигналов находятся в состоянии каждого процесса, то есть все потоки в процессе совместно используют один и тот же набор установленных функций обработчика сигналов.Сигнальные маски находятся в состоянии потока. Сигналы могут быть заблокированы или разблокированы для каждого потока.Сигналы могут быть ориентированы на процесс или поток. Если сигнал направлен на процесс, то для его обработки выбирается произвольный поток, который в настоящее время не имеет заблокированного типа сигнала.

Простой способ обработки сигналов в многопоточном приложении - создать один поток в качестве отдельного потока обработки сигналов. Все сигналы интереса блокируются в каждом потоке; обработчики сигналов не установлены; и вызов потока обработки сигналовsigwaitinfo() в цикле, действуя на сигналы, как онире получил.

Это означает, что вы нене нужно беспокоиться о том, являются ли функции, которые вы хотите вызватьасинхронному сигнал безопасно или нет, потому что сигналы необрабатываются в обработчиках сигналов - ониобрабатывается синхронно вашим выделенным потоком обработки сигналов, который может вызывать любые функции, которые ему нравятся (например, он может использовать обычные функции синхронизации pthreads для пробуждения другого потока).

Ваш ответ на вопрос