Гарантированно ли обрабатывается сигнал, отправленный с kill в родительский поток, перед следующим оператором? - PullRequest
0 голосов
/ 24 апреля 2010

Хорошо, поэтому, если я работаю в дочернем потоке в Linux (используя pthreads, если это имеет значение), и я запускаю следующую команду

kill(getpid(), someSignal);

отправит данный сигнал родителю текущего потока.

Мой вопрос: гарантируется ли, что родительский процесс немедленно получит процессор и обработает сигнал (убивает приложение, если это SIGKILL, или делает что-то еще, если это какой-то другой сигнал) до запуска оператора, следующего за kill()? Или возможно - даже вероятно - что любая команда, следующая за kill(), будет выполняться до того, как сигнал будет обработан родительским потоком?

Ответы [ 3 ]

5 голосов
/ 24 апреля 2010

Нет, это не гарантировано.

Как правило, вы не можете делать какие-либо предположения о времени событий, происходящих в отдельных потоках (или процессах), если вы не используете явный механизм синхронизации (например, phtread_mutex или семафор).

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

3 голосов
/ 24 апреля 2010

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

И если вызов sigprocmask () замаскировал сигнал во всех потоках, сигнал будет действовать только после того, как он разоблачен.

Сигналы не отправляются в какой-либо конкретный поток, если вы не использовали sigprocmask для маскировки их из потоков, которые вы не хотите получать. Большинство многопоточных программ делают это, поскольку передача сигналов уровня процесса в произвольные потоки обычно не то, что вам нужно.

1 голос
/ 16 ноября 2017

Сигналы, отправляемые процессу (группе потоков), могут, как правило, доставляться любому потоку, и у вас, как правило, нет гарантии, что обработчик завершит работу до возврата вызова kill.

Если вы запустите

kill(getpid(), someSignal);

в многопоточном процессе, тогда вы можете быть уверены, что ваш sighandler запустится до того, как kill вернется в очень специфическом сценарии, где все, кроме вызывающих потоков, заблокированы someSignal (в этом случае обработчик sig будет запущен из потока, вызывающего kill).

См http://pubs.opengroup.org/onlinepubs/009695399/functions/kill.html:

Если значение pid вызывает генерацию sig для отправки процесс, и если sig не заблокирован для вызывающего потока, и если нет другой поток разблокировал sig или ожидает в функции sigwait () для сиг - либо сиг, либо хотя бы один ожидающий разблокированный сигнал доставляется в поток отправки перед возвратом kill ().

...