Обработка сигналов сиграцией

Я читал об использовании системного вызова 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(), о чем рассказывается в статье.

Другие вопросы по тегам