1

このコードとコメントに出くわしたとき、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によって設定されたハンドラーによって処理されません(私は知っています) 、ばかげているように聞こえます)

説明してください!!

4

1 に答える 1

2

記事のコンテキストでそのコードを確認する必要があります。コードは、信号が中断されるように調整しようとしていselect()ます。言及された競合状態は、シグナルハンドラーが何らかの形で失敗したり、失敗したりすることはありません-呼び出しと呼び出しsigaction()の間でシグナルが配信される可能性があることに注意してください。これにより、そのパターンは目的の結果を達成するために受け入れられなくなります。の前、最中、または後のいずれであっても、後で到着するシグナルが処理されるのは正しいことです。ただし、これを使用して の早期中断パスを確実に提供することはできません。これは、記事のコンテキストに関するものです。sigaction()select()sigaction()signal()select()

于 2012-06-21T19:14:29.660 に答える