Используя sigprocmask для реализации блокировок

Я реализую пользовательские потоки в ядре Linux 2.4, и я использую ualarm для вызова контекстных переключений между потоками.

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

Однако похоже, что я должен сделать довольно много для реализации этого:

sigset_t new_set, old_set;

sigemptyset(&new_set);
sigaddset(&new_set, SIGALRM);
sigprocmask(SIG_BLOCK, &new_set, &old_set);

Это блокирует SIGALARM, но он делает это с 3 вызовами функции! Много может произойти во время, которое требуется, чтобы эти функции работали, включая отправляемый сигнал. Лучшая идея я должен был смягчить это, временно отключала ualarm, как это:

sigset_t new_set, old_set;

time=ualarm(0,0);
sigemptyset(&new_set);
sigaddset(&new_set, SIGALRM);
sigprocmask(SIG_BLOCK, &new_set, &old_set);
ualarm(time, 0);

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

1
задан EpsilonVector 18 May 2010 в 01:46
поделиться

3 ответа

Как указывает WhirlWind , функции набора сигналов довольно легкие и даже могут быть реализованы как макросы; и вы также можете просто сохранить набор сигналов, содержащий только SIGALRM , и использовать его повторно.

Тем не менее, на самом деле не имеет значения , происходит ли сигнал во время вызовов sigaddset () или sigemptyset () - new_set и old_set переменные (предположительно) локальные для потока, и критическая секция не входит до тех пор, пока не вернется sigprocmask () .

1
ответ дан 3 September 2019 в 00:29
поделиться

Вы обнаружите, что sigemptyset () и sigaddset () в signal.h - это просто макросы или встроенные функции, поэтому они выполняются встроенно в вашем код. Просто используйте переменную стека при их вызове.

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

Кстати, я не уверен, как вы используете ualarm, но если вы не улавливаете или не игнорируете SIGALARM при первом вызове, вы, вероятно, убьете свой процесс.

1
ответ дан 3 September 2019 в 00:29
поделиться

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

0
ответ дан 3 September 2019 в 00:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: