В системах UNIX доставка и обработка сигналов производится на уровне процесса. В многонитевых системах необходимо определять, какой из LWP процесса будет заниматься обработкой сигналов. При использовании прикладных нитей имеется аналогичная проблема: после того, как ядро передаст сигнал в LWP, нитевая библиотека должна определить, в какую нить его направить.
Существует несколько вариантов решения данной проблемы: • пересылка сигналов каждой нити; • объявление одной из нитей процесса «главной», после чего все сигналы передаются только этой нити; • отправка сигналов в любую произвольно выбранную нить; • использование эвристических методов для определения, какой из нитей необходимо отправить данный сигнал; • создание новой нити для обработки каждого сигнала.
Первый метод является очень затратным, и, более того, он несовместим с большинством обычных ситуаций, в которых используются сигналы. Однако в некоторых случаях он весьма удобней. Например, если пользователь нажимает комбинацию Ctrl+Z на терминале, он может желать приостановки всех нитей процесса. Второй метод приводит к асимметричной обработке нитей, что несовместимо с современным подходом к нитям и с симметричными многопроцессорными системами, часто ассоциируемыми с многонитевыми ядрами. Последнее решение, приведенное в списке, подходит только для определенных ситуаций.
Выбор между двумя оставшимися методами зависит от природы выработанного сигнала. Некоторые сигналы, например SIGSEGV (ошибка сегментации) и SIGILL (непредусмотренное исключение), создаются вследствие действий нити. Наиболее удобным решением в данном случае представляется доставка такого сигнала той нити, которая и стала причиной его возникновения. Другие сигналы, такие как SIGSTP (сигнал остановки, вырабатываемый терминалом) или SIGINT (сигнал прерывания), создаются при возникновении внешних событий и не могут быть как-то ассоциированы с конкретной нитью процесса.
Еще одним аспектом, о котором стоит упомянуть, является применяемый метод обработки и маскирования сигналов. Должны ли все нити использовать общий набор обработчиков сигналов или каждая будет определять свой собственный? Хотя последний вариант является более гибким и универсальным, он привносит каждой нити дополнительные затраты, что противоречит главной цели применения многонитевых процессов. Такие же проблемы возникают при маскировании сигналов, поскольку обычно маскирование происхо¬дит с целью защиты важных участков кода. Следовательно, лучшим вариантом представляется разрешение каждой нити на указание собственной маски сигналов. Перегрузки, возникающие при применении таких масок, менее значительны и поэтому более приемлемы.