C++ 多线程进程中的信号处理

C++ 多线程进程中的信号处理,c++,multithreading,signals,C++,Multithreading,Signals,我在处理多线程进程中的信号时遇到了一个基本问题 在我的代码中,我从主线程创建了一个子线程,以侦听稍后将由主线程触发的SIGALRM(使用其他函数,如timer\u create会给出相同的结果,因此请不要关注这个) 问题在于,整个过程没有捕捉到信号,而是在控制台上以奇怪的“闹钟”输出结束 这是我的代码: #include <iostream> #include <sys/time.h> #include <unistd.h> #include <csig

我在处理多线程进程中的信号时遇到了一个基本问题

在我的代码中,我从主线程创建了一个子线程,以侦听稍后将由主线程触发的
SIGALRM
(使用其他函数,如
timer\u create
会给出相同的结果,因此请不要关注这个)

问题在于,整个过程没有捕捉到信号,而是在控制台上以奇怪的“闹钟”输出结束

这是我的代码:

#include <iostream>
#include <sys/time.h>
#include <unistd.h>
#include <csignal>

using namespace std;

void* run_something(void* args){
    //unblock the SIGALRM to be catched
    sigset_t sig;
    sigemptyset(&sig);
    sigaddset(&sig, SIGALRM);
    sigprocmask(SIG_UNBLOCK, &sig, NULL); //tried with pthread_sigmask

    //wait for SIGALRM
    int catchedSig;
    sigwait(&sig, &catchedSig);
    cout<<"in sub-thread, SIGALRM catched, return"<<endl;
}

int main(int argc, char** argv){
    //block SIGALRM in main thread
    sigset_t sig;
    sigemptyset(&sig);
    sigaddset(&sig, SIGALRM);
    sigprocmask(SIG_BLOCK, &sig, NULL);

    //create new thread
    pthread_t thread;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_create(&thread, &attr, run_something, NULL);

    //trigger SIGARLM after 2s
    alarm(2); //tried with timer_create/sigevent

    //wait
    cout<<"in main thread, waiting for sub-thread to terminate"<<endl;
    pthread_join(thread, NULL);
    cout<<"in main thread, terminating"<<endl;

    return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
使用名称空间std;
void*run\u某物(void*args){
//解锁要捕获的信号
sigset_t sig;
sig&sig;
sigaddset(&sig,SIGALRM);
sigprocmask(SIG_UNBLOCK,&SIG,NULL);//尝试使用pthread_sigmask
//等待信号
int-catchedSig;
sigwait(&sig,&catchedSig);

cout显示的代码没有为
SIGARLM
设置任何信号处理程序

因此,在接收信号时,操作系统会按其应该的方式进行调用,即终止进程。顺便说一句,将“闹钟”打印到控制台是默认行为的一部分

要解决此问题,请为
SIGARLM
设置一个信号处理程序。这可以通过使用以便携方式完成


也不要在多线程程序中使用,因为其行为未指定。请改用


更新

我错过了代码调用
sigwait()
…:}

在这种情况下,修复此问题并不需要设置信号处理程序(该处理程序仍然可以解决问题,并且是有效的),而是按照的建议进行设置,即在调用
sigwait()
(或
sigwaitinfo()
)之前阻止信号

此外,出于上述原因,请确保使用
pthread\u sigmask()
而不是
sigprocmask()


与问题无关:

我从主线程创建一个子线程


没有“子线程”这样的概念。创建之后,所有进程的线程都是同一级别上的“兄弟线程”。这包括使用
main()
启动的初始线程。“main”-线程通常以这种方式调用,只是因为它的线程函数的名称:
main

您的
run\u something
线程在调用
sigwait
该信号之前解除SIGALRM的阻塞,但是
sigwait
从挂起(即阻塞)信号集中删除一个信号


<不要在你的线程中解锁,你会看到你期望的行为。

我怀疑C++的行为与C实现不同。CherubimAnand@CherubimAnand:我想我会对那些在CI中搜索相同内容的人有用,我会说“main”线程有一个不同之处-在
return()
from
main()
时,进程退出,所有线程终止。传递给
pthread\u create()
的函数中的
return()
将简单地终止该线程。我觉得这一点很重要,因为我看到有很多问题都在问为什么进程在使用
main()
启动线程时突然终止,然后立即调用
return()
。是的,这很公平。但是,如果
main()
pthread\u exit()
结束,则不会有什么区别@安德烈·温莱斯利,因为你在回答中弄乱了,所以把它往后退了!指向我要添加/更新的'sigwait()文档的链接: