Как стать автором
Обновить

Как безопасно доставить SIGINT в главный поток?

Время на прочтение2 мин
Количество просмотров1.2K
Автор оригинала: Raymond Chen
Комментатор AnotherMatt удивляется, почему консольные Win32 приложения доставляют сообщения в другой поток. Почему они не посылают их главному потоку?

На самом деле, у меня обратный вопрос. Почему в UNIX сигнал посылается главному потоку? Это делает практически невозможным сделать что-нибудь важное внутри обработчика сигнала. Главный поток может быть внутри менеджера кучи (удерживать критическую секцию) во время приёма сигнала. Если обработчик сигнала попытается получить доступ к куче, то произойдет взаимная блокировка с самим собой, если вам повезёт. В худшем варианте повредится куча.

Для примера рассмотрим этот обработчик:

void catch_int(int sig_num)
{
/* Переустанавливаем обработчик сигнала снова на catch_int */
signal(SIGINT, catch_int);

/* и выводим сообщение */
printf("Не делайте этого");
fflush(stdout);
}

Что случится, если сигнал послан, когда программа выполняла свою fflush(), скажем, после того, как уже была записана половина буфера? Если два потока вызывают fflush(), второй вызывающий будет ждать окончание первого. Но здесь всё происходит в одном и том же потоке; второй вызывающий не может ждать первого, поскольку первый не может работать, пока второй не вернет значение!

(Заметим также, что этот обработчик потенциально модифицирует переменную errno, что может привести к «невозможным» ошибкам в главной программе.)

Win32 не верит в асинхронное прерывание кода пользовательского режима другим пользовательским кодом, потому что это делает невозможным определение состояния процесса. Доставка сигнала второму потоку означает то, что если второй поток попытается получить доступ к куче, пока первый поток владеет ей — второй поток будет покорно ждать стабильного состояния кучи и только после её освобождения начнёт работу с ней.


UPD: всем спасибо за карму. перенес в специализированный блог.
Теги:
Хабы:
+3
Комментарии5

Публикации

Изменить настройки темы

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн