Я пытаюсь создать оболочку в Linux, которая контролирует, сколько одновременных выполнений чего-либо разрешено одновременно. Для этого я использую общесистемный счетный семафор. Я создаю семафор, делаю sem_wait()
, запускаю дочерний процесс и затем делаю sem_post()
, когда дочерний процесс завершается. Это хорошо.
Проблема заключается в том, как безопасно обрабатывать сигналы, отправляемые в эту оболочку. Если он не перехватывает сигналы, команда может завершиться без выполнения команды sem_post()
, что приведет к постоянному уменьшению числа семафоров на единицу. Итак, я создал обработчик сигнала, который делает sem_post()
. Но все же есть проблема.
Если обработчик подключен до выполнения sem_wait()
, сигнал может поступить до завершения sem_wait()
, в результате чего sem_post()
происходит без sem_wait()
. Обратное возможно, если я сделаю sem_wait()
перед настройкой обработчика сигнала.
Очевидным следующим шагом было блокирование сигналов во время настройки обработчика и sem_wait()
. Это псевдокод того, что у меня сейчас:
void handler(int sig)
{
sem_post(sem);
exit(1);
}
...
sigprocmask(...); /* Block signals */
sigaction(...); /* Set signal handler */
sem_wait(sem);
sigprocmask(...); /* Unblock signals */
RunChild();
sem_post(sem);
exit(0);
Проблема в том, что sem_wait()
может блокировать, и в течение этого времени сигналы блокируются. Пользователь, пытающийся убить процесс, может в конечном итоге прибегнуть к «kill -9», поведение, которое я не хочу поощрять, поскольку я не могу справиться с этим делом, несмотря ни на что. Я мог бы использовать sem_trywait()
в течение небольшого времени и протестировать sigpending()
, но это влияет на справедливость, потому что больше нет гарантии того, что процесс, ожидающий семафор, самый длинный, будет запущен следующим.
Есть ли здесь действительно безопасное решение, которое позволяет мне обрабатывать сигналы во время захвата семафора? Я подумываю прибегнуть к глобальному «Есть ли у меня семафор» и снять блокировку сигналов, но это не на 100% безопасно, так как получение семафора и установка глобального не атомарны, но могут быть лучше, чем блокировка сигналов во время ожидания. *