Почему sem_wait
нельзя использовать внутри обработчика сигналов (в частности, сигнала SIGSEGV для каждого потока)? Может ли кто-нибудь дать мне пример сценария, когда это приведет к сбою приложения? Я предполагаю, что sem_wait
является одновременно повторно используемым и поточно-ориентированным, так в чем здесь проблема? Почему это не асинхронно безопасно?
sem_wait и обработчик сигналов
Ответы (3)
Асинхронная безопасность — гораздо более строгое требование, чем многопоточная безопасность. Вы можете написать потокобезопасный код, используя примитивы для защиты глобальных данных с помощью критических секций. Обработчики сигналов не могут полагаться на это. Например, вы можете находиться внутри критической секции внутри sem_wait и одновременно делать что-то, что вызывает segfault. Это нарушит защиту многопоточности sem_wait.
sem_wait нельзя использовать в обработчике сигнала по этой причине:
Поток A вызывает sem_wait для sem1. Когда поток A завершается, он отправляет сообщения в sem1. Однако, прежде чем он может завершиться, сигнал получен, а затем вводится обработчик, вызывающий sem_wait на sem1. Поскольку A будет отправлять сообщения в sem1, обработчик никогда не вернется, и у вас возникнет взаимоблокировка. Вот почему хорошим правилом является никогда ничего не ждать в обработчике сигнала. Проблема, ASFAIK, больше связана с взаимоблокировкой, чем со сбоем.
Кроме того, это нарушает идеальную цель обработчика сигналов, которая заключается в обработке внешнего прерывания и последующем быстром возвращении к тому, что вы делали.
Наконец, не лучше ли избавиться от SIGSEGV вместо того, чтобы его обрабатывать?
Что, если приложение получает сигнал, когда значение семафора равно нулю, а поток, который получает сигнал, оказывается тем, который должен увеличить значение семафора (sem_post)? Если вы затем вызовете sem_wait в обработчике сигнала, процесс заблокируется, не так ли?
Другим аргументом, конечно, может быть то, что если sem_wait отсутствует в списке функций, безопасных для асинхронных сигналов, реализация может свободно вызывать носовых демонов.
sem_wait(&x)
сsem_wait(&x)
на том жеx
, очевидно, является проблемой, но это должно быть выполнимо с другим семафором, хотя технически это все еще неопределенное поведение. - person PSkocik   schedule 15.11.2017