2

最近、シグナルを使用したプログラミングを始めました。C のマルチスレッド サーバー コードでそれらを使用しました。シグナルに関連するコードの一部を次に示しますが、正常に機能しません。

シグナルハンドラ:

void* Ctrl_C_handler(void *arg)
{
int *sock_fd_ptr = (int*)arg;
sigset_t set;
int err, sig;

err = sigemptyset(&set);                // Clear the signals holder set
if(err) perror("sigemptyset(&set)");

err = sigaddset(&set, SIGINT);          // Add the SIGINT: Ctrl+C
if(err) perror("siaddset(&set, SIGINT)");

err = pthread_sigmask(SIG_UNBLOCK, &set, NULL); // Set mask as to unblock SIGINT
if(err) perror("pthread_sigmask(SIG_SETMASK, &set, NULL)");

printf("Signal handler active:\n");
while(1)        // Ctrl+C
{
    err = sigwait(&set, &sig);          // Wait for signal to occur
    if(err)
    {
        perror("sigwait(&set, &sig)");
        printf("Error handling the signal, SigHandlerThread exiting..\n");
        break;
    }

    if(sig == SIGINT)
    {
        printf("Ctrl+C detected by server !!\n");
        printf("No more connections will be accepted!!");
        if(*sock_fd_ptr > 0)
        {
            close(*sock_fd_ptr);
            *sock_fd_ptr = -1;
            break;
        }
    }   
}
return NULL;

}

Main() の内部:

/*********** Signal Handling *************/

sigset_t set;                       // declare a set to hold the signals 
err = sigfillset(&set);             // Fill the set with all the signals
if(err) perror("sigfillset(&set)");

err = sigthreadmask(SIG_BLOCK, &set, NULL);  // Block/Mask the signals in the set
if(err) perror("sigthreadmask(SIG_BLOCK, &set, NULL)");

err = pthread_create(&sig_handler_tid, NULL, Ctrl_C_handler, (void *)&sock_fd);
                                    // Create a thread for handling signals
if(err) perror("pthread_create");

私はこの方法をここで読んだ。kill -s SIGINT <pid of my program>別の端末ウィンドウから送信しようとしましたが、プログラムが終了します。

4

1 に答える 1

2

SIGINT がプロセスに送信されると、ブロックが解除された唯一のスレッドであるスレッドに配信されCtrl_C_handlerます。シグナル配信とは、シグナルに関連付けられているアクションを実行することを意味し、SIGINT のデフォルトのアクションは、ご存知のようにプロセスの終了です。

しかし、意図したように sigwait() が冷静にシグナルを傍受しないのはなぜでしょうか?

sigwait() は、保留中のシグナルのマスクからシグナルを削除するように設計されています。つまり、シグナル配信の通常の非同期ドラマなしで、配信が中断された (SIG_BLOCKed) 生成されたシグナルです。

したがって、スレッドで SIG_UNBLOCK SIGINT を実行しないでください。代わりに、ブロックしたままにしておくと、コードは意図したとおりに機能します。提供された参照を精査すると、そのサンプル コードが sigwait() を呼び出す前にすべてのシグナルをブロックすることがわかります。

于 2013-08-22T12:57:41.550 に答える