Linux эквивалент перехватов Windows

#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) обрабатывает байт.