Обработчик сигнала, обращающийся к структуре данных очереди (состояние гонки?) - PullRequest
6 голосов
/ 16 ноября 2011

В настоящее время я пишу небольшую оболочку на C ++.

Задания и связанные с ними PID хранятся в очереди указателей заданий (job *).При запуске нового задания информация о нем добавляется в очередь.Поскольку несколько заданий могут обрабатываться одновременно и новые задания могут быть введены в консоли оболочки в любое время, у меня есть обработчик сигнала для ожидания завершенных заданий.

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

В таком случае его операция очереди insert будет приостановлена ​​и будет вызван мой обработчик сигнала, чтовыполнит операцию pop.

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

Я вижу некоторую информацию о том, что C++11 способен к атомарным операциям, как объявлено пользователем, наряду сс информацией о тасклетах.Я не уверен, что они имеют отношение к моему вопросу.

Интересно, что пример оболочки (MSH - http://code.google.com/p/mini-shell-msh/), которую я использую в качестве ссылки, похоже, не выполняет какой-либо обработкитакие условия. Обработчик сигнала сразу же изменяет список заданий вместе с главной консолью. Возможно, здесь есть что-то, что я пропускаю?

Как всегда, вся обратная связь оценивается.

Ответы [ 2 ]

4 голосов
/ 16 ноября 2011

У вас есть несколько способов избежать состояния гонки.

  • Использовать очередь ожидания (атомарную) для указателей заданий;
  • использовать любой другой тип очереди, но защитить ее с помощью sigprocmask (в коде не обработчика) и с правильным значением sa_mask в вызове sigaction;
  • вообще не используйте обработчик сигналов, используйте некоторый непереносимый системный вызов, который позволяет работать с сигналами синхронно: в Linux это возможно с signalfd, не уверен в других платформах.
1 голос
/ 16 ноября 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...