子线程提高它忽略的信号

问题描述:

在错误情况下,我想允许子线程发出一个信号,然后由父线程捕获该信号。另一个线程然后安全地终止整个过程。我看到的问题是,如果我在创建过程中使用pthread_sigmask阻止子线程接收信号,那么它引发的信号不会被其他线程看到。这是预期的行为?我能做些什么呢?子线程提高它忽略的信号

我检查了here和其他许多人喜欢它,但他们处理的信号源于外部过程。

示例代码如下,请原谅在信号处理程序中使用不允许的函数,因为它便于举例。我在这里使用了SIGABRT,因为它有一个非常明显的默认处理程序,但如果使用SIGUSR1,行为是相同的。

#include <unistd.h> 
#include <signal.h> 
#include <iostream> 
#include <thread> 

void sigHandler(int) 
{ 
    std::cout << "Caught signal in " << std::this_thread::get_id() << std::endl; 
} 

void threadMain() 
{ 
    std::cout << "Child is " << std::this_thread::get_id() << std::endl; 
    sleep(1); 
    raise(SIGABRT); 
    std::cout << "Child exiting" << std::endl; 
} 

int main(int argc, char** argv) 
{ 
    std::cout << "Parent is " << std::this_thread::get_id() << std::endl; 
    struct sigaction psa; 
    psa.sa_handler = sigHandler; 
    sigaction(SIGABRT, &psa, nullptr); 
    sigset_t set; 
    sigemptyset(&set); 
    sigaddset(&set, SIGABRT); 
    if (argc > 1) 
    { 
    if (pthread_sigmask(SIG_BLOCK, &set, NULL) == 0) 
     std::cout << "Masking complete" << std::endl; 
    else 
     std::cout << "Failed to mask" << std::endl; 
    } 
    std::thread child(threadMain); 
    if (argc > 1) 
    { 
    if (pthread_sigmask(SIG_UNBLOCK, &set, NULL) == 0) 
     std::cout << "Unmask complete" << std::endl; 
    else 
     std::cout << "Failed to mask" << std::endl; 
    } 
    sleep(2); 
    child.join(); 
} 

如果您编译

g++ --std=c++11 -lpthread main.cpp -g -o main 

./main运行输出是:

Parent is 140042782496544 
Child is 140042766427904 
Caught signal in 140042766427904 
Child exiting 

所以信号被抓住了,但孩子(不是父,像我通缉)。如果您有./main 1运行它的输出是:

Parent is 140070068569888 
Masking complete 
Unmask complete 
Child is 140070052501248 
Child exiting 

即信号堵塞了,所以孩子没看出来(这是我想要的东西),但家长没看到。

如何确保信号由小孩抚养并且由父母抚养?

+0

为什么不使用C++异常? –

manual for raise(3)似乎表明,它发出的信号明确调用线程,而不是整个过程,所以由一个线程提出的信号不会被看出其他:

raise()函数将信号发送到所述主叫进程或线程。在单线程程序就相当于

 kill(getpid(), sig); 

在多线程程序就相当于

 pthread_kill(pthread_self(), sig); 

改变raise(SIGABRT)明确地kill(getpid(), SIGABRT)似乎做你想要什么,并发送发信号给整个过程,所以它被一些没有被阻塞的线程捕获。

+0

这就是解决它,使用杀死是一个很好的解决方案。谢谢! – Obiphil

听起来像你想要提高()有线程通信 - 嗯,它不。所以你想要做的是不可能的。

但是,您可以设置一个变量,或者在处理程序中使用任何其他线程通信来向主线程报告该信号已被引发。

或者,你可以使用pthread_kill ...