#windows #linux #ipc #signals
#Windows #linux #ipc #сигналы
Вопрос:
Я хотел бы знать, как выразить что-то вроде перехвата Windows в Linux.
У меня есть приложение Linux с различными потоками. Основной поток, для которого в настоящее время установлен обработчик сигналовctrlc, перехватывает его и завершает работу приложения.
Я бы хотел, чтобы другой поток в приложении сначала обработал ctrlcсобытие, а затем передал его в основной поток.
Ответ №1:
Насколько я знаю, это было бы сложно сделать. Сигналы Unix являются примитивными.
По умолчанию сигналы доставляются в случайный поток. Чтобы обойти это, обычно используется трюк, чтобы блокировать сигналы во всех потоках, кроме одного. Самый простой способ сделать это — заблокировать все сигналы в main с pthread_sigmask
помощью , затем создать потоки (которые унаследуют маску сигнала), а затем создать отдельный поток, который выполняет a sigwait/sigwaitinfo
для заблокированных сигналов. Это заставляет сигналы доставляться в этот поток.
После использования сигнала в потоке улавливания сигнала вам нужно будет выполнить a pthread_kill
с идентификатором потока main и номером перехваченного сигнала, чтобы переслать сигнал в main. Проблема в том, что main заблокировал бы его.
На самом деле вы не можете разблокировать main и заблокировать поток, улавливающий сигнал, перед пересылкой сигнала, потому что это условие гонки — ничто не мешает второму сигналу поступать, а поток, улавливающий сигнал, не видит его. Это сводит на нет все усилия.
Вы могли бы заставить сигнальный поток отправить сообщение в main через какую-либо другую форму IPC (канал или что-то еще) со словами «пойман XX, примите соответствующие меры». Может быть, этого достаточно?
Может быть, у кого-то есть какая-то умная идея, но я подозреваю, что суть в том, что это просто не так, как это обычно делается в unix.
Ответ №2:
Другой трюк (предложенный документацией Qt) может заключаться в том, чтобы иметь обработчик сигнала, записывающий (например, один байт) в канал, и иметь некоторый поток, pr просто какой-то обработчик событий (например, g_io_add_watch с GTK) обрабатывает байт.