在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发送到该过程。由于sigmask设置包括SIGINT,此时接收到的SIGINT信号在信号列表中处于待处理状态。在pthread_create之后,在新线程中,sigpending返回调用线程的挂起信号,并且SIGINT包含在集合中。所以它与手册页不一致。
感谢任何帮助。
答案 0 :(得分:1)
我认为问题在于您发送的信号是一个进程级信号,因此它在整个进程(以及阻止它的所有线程)中都处于待处理状态,无论它是否在创建线程之前处于挂起状态。 docs for sigpending()
说(重点补充):
sigpending()
函数应在set参数引用的位置存储阻止传递给调用线程且待处理的进程的信号集或调用线程。
如果调用pthread_create()
时挂起的信号是线程级信号,那么它将不会在新创建的线程上挂起。您可以使用pthread_kill(pthread_self(), SIGINT)
函数发送信号来测试此信息。
我确实同意有关新线程的待处理信号被清除的措辞不是很明确。