新创建线程的信号挂起列表不为空?

Posted

技术标签:

【中文标题】新创建线程的信号挂起列表不为空?【英文标题】:signal pending list of new created thread is not empty? 【发布时间】:2011-12-27 10:00:53 【问题描述】:

在pthread_create 的手册页中,它说:“新线程的未决信号集为空”。 但是我写了一些代码进行测试,得到了相反的结果,新创建的线程的信号挂起列表不为空。代码如下:

void* thread_fun(void* arg)

    int s;
    sigset_t pendingset;

    s = sigemptyset(&pendingset);
    if(s != 0)
    
        printf("sigempty error.\n");
    
    else
        s = sigpending(&pendingset);
        if(s == 0)
            if(sigismember(&pendingset, SIGINT))
                printf("SIGINT in pending signal list.\n"); // this msg is printed
        
    

    return NULL;


int main()

    pthread_t tid;
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    pthread_sigmask(SIG_BLOCK, &set, NULL);

    sleep(10); // send SIGINT to the process using kill -SIGINT pid
    printf("before create thread...\n");
    pthread_create(&tid, NULL, thread_fun, NULL);

    pthread_join(tid, NULL);

    return 0;

在睡眠期间,我向进程发送了 SIGINT。因为包含 SIGINT 的 sigmask 集,此时接收到的 SIGINT 信号在信号列表中处于未决状态。在 pthread_create 之后,在新线程中,sigpending 返回调用线程的未决信号,并且 SIGINT 包含在集合中。所以它与手册页不一致。

感谢任何帮助。

【问题讨论】:

【参考方案1】:

我认为问题在于您发送的信号是进程级信号,因此它对于整个进程(以及所有阻塞它的线程)都是待处理的,无论它在创建线程之前是否处于待处理状态。 docs for sigpending() 说(强调):

sigpending() 函数应在 set 参数所引用的位置存储一组信号,这些信号被阻止传递给调用线程,并且在 进程上 或调用线程。

如果调用pthread_create() 时挂起的信号是线程级信号,那么它不会在新创建的线程上挂起。您可以通过使用pthread_kill(pthread_self(), SIGINT) 函数发送信号来测试这一点。

我同意关于为新线程清除挂起信号的措辞对此不是很清楚。

【讨论】:

感谢您的回答。而且我还从 die 中的 sigpending() 手册页中找到了解释:线程未决的信号集是该线程未决的信号集和该线程未决的信号集的并集整个过程

以上是关于新创建线程的信号挂起列表不为空?的主要内容,如果未能解决你的问题,请参考以下文章

C中线程信号控制

C ++中的条件变量问题

使用 pthreads 在挂起模式下创建线程

Linux 线程线程同步《三》

尽管有线程,Qt GUI 仍挂起

线程生命周期