Обработка сигналов сиграцией
Я читал об использовании системного вызова pselect, когда наткнулся на этот код и комментарии...
static void handler(int sig) { /* do nothing */ }
int main(int argc, char *argv[])
{
fd_set readfds;
struct sigaction sa;
int nfds, ready;
sa.sa_handler = handler; /* Establish signal handler */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sigaction(SIGINT, &sa, NULL);
/* ... */
ready = select(nfds, &readfds, NULL, NULL, NULL);
/* ... */
}
this solution suffers from a race condition: if the SIGINT signal is delivered after
the call to sigaction(), but before the call to select(), it will fail to interrupt
that select() call and will thus be lost.
теперь я не уверен в системном вызове sigaction... изначально я думал, что он как бы сохраняет обработчик, соответствующий сигналу, и все... когда сигнал поступает, он ищет его обработчик и выполняется обработчик... но если это правильно, тогда обработчик, соответствующий сигналу, будет сохранен для всей программы, и он будет выполняться всякий раз, когда поступает сигнал... так, как бы мала ни была продолжительность между sigaction и select, сигнал будет обработан...
но этот код создает впечатление, что сигнал обрабатывается только тогда, когда он совпадает с вызовом / выполнением sigaction... после завершения вызова сигнал не будет обработан обработчиком, установленным sigaction для остальной части программы (что я знаю звучит абсурдно)
пожалуйста, объясни!!
1 ответ
Вы должны взглянуть на этот код в контексте статьи - код пытается организовать сигнал для прерывания select()
, Упомянутое состояние гонки не вызывает sigaction()
или обработчик сигнала для сбоя в любом случае - он просто заметил, что есть вероятность, что сигнал может быть доставлен между sigaction()
вызов и select()
вызов, который делает эту модель неприемлемой для достижения желаемого результата. Вы правы, что сигнал приходит в любое время после sigaction()
будет обрабатываться, будь то до, во время или после signal()
, Однако это не может быть использовано для надежного обеспечения раннего пути прерывания для select()
, о чем рассказывается в статье.