Пазл Состояние гонки в C обработчики сигналов - PullRequest
6 голосов
/ 02 ноября 2010

Мне нужно знать, как избежать состояния гонки при обработке сигналов в C. Каждый раз, когда моя программа получает сигнал, я хочу, чтобы она изменила (глобальный) связанный список. Жизненно важно, чтобы я не пропустил сигнал, и не менее важно, чтобы глобальный связанный список, который я изменяю, не был изменен во время выполнения обработчика.

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

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

Ответы [ 4 ]

1 голос
/ 02 ноября 2010

Вы можете маскировать сигналы во время выполнения обработчика сигналов - отметьте sa_mask поле struct sigaction, которое вы передаете sigaction() системному вызову.

1 голос
/ 02 ноября 2010

С http://users.evtek.fi/~tk/rtp/signals-programming.html:

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

1 голос
/ 02 ноября 2010

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

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

0 голосов
/ 02 ноября 2010

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

...