sem_wait и обработчик сигналов

Почему sem_wait нельзя использовать внутри обработчика сигналов (в частности, сигнала SIGSEGV для каждого потока)? Может ли кто-нибудь дать мне пример сценария, когда это приведет к сбою приложения? Я предполагаю, что sem_wait является одновременно повторно используемым и поточно-ориентированным, так в чем здесь проблема? Почему это не асинхронно безопасно?


person MetallicPriest    schedule 13.12.2011    source источник
comment
Я предлагаю вам добавить, от каких типов операций (потоки, прерывания, исключения и т. д.) вас должен защищать семафор. Это имеет большое значение.   -  person gnometorule    schedule 13.12.2011
comment
Связано: stackoverflow.com/questions/ 14421951/ . Я думаю, что конфликт sem_wait(&x) с sem_wait(&x) на том же x, очевидно, является проблемой, но это должно быть выполнимо с другим семафором, хотя технически это все еще неопределенное поведение.   -  person PSkocik    schedule 15.11.2017


Ответы (3)


Асинхронная безопасность — гораздо более строгое требование, чем многопоточная безопасность. Вы можете написать потокобезопасный код, используя примитивы для защиты глобальных данных с помощью критических секций. Обработчики сигналов не могут полагаться на это. Например, вы можете находиться внутри критической секции внутри sem_wait и одновременно делать что-то, что вызывает segfault. Это нарушит защиту многопоточности sem_wait.

person TJD    schedule 13.12.2011

sem_wait нельзя использовать в обработчике сигнала по этой причине:

Поток A вызывает sem_wait для sem1. Когда поток A завершается, он отправляет сообщения в sem1. Однако, прежде чем он может завершиться, сигнал получен, а затем вводится обработчик, вызывающий sem_wait на sem1. Поскольку A будет отправлять сообщения в sem1, обработчик никогда не вернется, и у вас возникнет взаимоблокировка. Вот почему хорошим правилом является никогда ничего не ждать в обработчике сигнала. Проблема, ASFAIK, больше связана с взаимоблокировкой, чем со сбоем.

Кроме того, это нарушает идеальную цель обработчика сигналов, которая заключается в обработке внешнего прерывания и последующем быстром возвращении к тому, что вы делали.

Наконец, не лучше ли избавиться от SIGSEGV вместо того, чтобы его обрабатывать?

person dbeer    schedule 13.12.2011

Что, если приложение получает сигнал, когда значение семафора равно нулю, а поток, который получает сигнал, оказывается тем, который должен увеличить значение семафора (sem_post)? Если вы затем вызовете sem_wait в обработчике сигнала, процесс заблокируется, не так ли?

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

person janneb    schedule 13.12.2011