sigwait()和信号处理程序

Lun*_*oms 7 c linux multithreading signals pthreads

如果我为SIGABRT设置和信号处理程序,同时我有一个线程在SIGBRT上等待sigwait()(我通过pthread_sigmask在其他线程中有一个阻塞的SIGABRT).

那么首先处理哪一个?信号处理程序或sigwait()?

[我正面临一些问题,sigwait()永远被阻止.我正在调试它]

main()
{
    sigset_t                    signal_set;

    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGABRT); 
    sigprocmask(SIG_BLOCK, &signal_set, NULL); 

    // Dont deliver SIGABORT while running this thread and it's kids.
    pthread_sigmask(SIG_BLOCK, &signal_set, NULL);

    pthread_create(&tAbortWaitThread, NULL, WaitForAbortThread, NULL);
    ..
    Create all other threads
    ...
}   

static void*    WaitForAbortThread(void* v)
{
    sigset_t signal_set;
    int stat;
    int sig;

    sigfillset( &signal_set);
    pthread_sigmask( SIG_BLOCK, &signal_set, NULL ); // Dont want any signals


    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGABRT);     // Add only SIGABRT

    // This thread while executing , will handle the SIGABORT signal via signal handler.
    pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); 
    stat= sigwait( &signal_set, &sig  ); // lets wait for signal handled in CatchAbort().
    while (stat == -1)
    {
        stat= sigwait( &signal_set, &sig  );
    }

    TellAllThreadsWeAreGoingDown();

    sleep(10);

    return null;
}

// Abort signal handler executed via sigaction().
static void CatchAbort(int i, siginfo_t* info, void* v)
{
    sleep(20); // Dont return , hold on till the other threads are down.
}
Run Code Online (Sandbox Code Playgroud)

在sigwait(),我会知道收到了SIGABRT.我将告诉其他线程.然后将保持中止信号处理程序,以便不终止进程.

我想知道sigwait()和信号处理程序的交互.

jeb*_*det 5

From sigwait() documentation :

The sigwait() function suspends execution of the calling thread until one of the signals specified in the signal set becomes pending.

A pending signal means a blocked signal waiting to be delivered to one of the thread/process. Therefore, you need not to unblock the signal like you did with your pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL) call.

This should work :

static void* WaitForAbortThread(void* v){
    sigset_t signal_set;

    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGABRT); 

    sigwait( &signal_set, &sig  );

    TellAllThreadsWeAreGoingDown();

    sleep(10);

    return null;
}
Run Code Online (Sandbox Code Playgroud)


rak*_*ib_ 1

从您发布的代码片段来看,您似乎使用了错误sigwait()。AFAIU,你需要WaitForAbortThread像下面这样:

     sigemptyset( &signal_set); // change it from sigfillset()
     for (;;) {
           stat = sigwait(&signal_set, &sig);

           if (sig == SIGABRT) {
          printf("here's sigbart.. do whatever you want.\n");
          pthread_kill(tid, signal); // thread id and signal
         }
       }
Run Code Online (Sandbox Code Playgroud)

我认为pthread_sigmask()其实并不需要。由于您只想处理 SIGABRT,因此首先将 signal_set 初始化为空,然后简单地添加SIGABRT,然后跳入无限循环,sigwait将等待您正在寻找的特定信号,您检查信号是否是 SIGABRT,如果是 - 执行任何操作你要。注意 的使用pthread_kill(),使用它向通过 tid 指定的其他线程发送任何信号以及您要发送的信号,请确保您知道要发送信号的其他线程的 tid。希望这会有所帮助!