gpt4 book ai didi

c++ - 子线程引发它忽略的信号

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:04:54 26 4
gpt4 key购买 nike

在错误情况下,我想允许子线程发出一个信号,然后由父线程捕获该信号。然后另一个线程安全地终止整个进程。我看到的问题是,如果我在创建期间使用 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

所以信号被捕获了,但是被 child 捕获了(不是 parent ,就像我想要的那样)。如果您使用 ./main 1 运行它,输出为:

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

即信号被屏蔽所以 child 没有看到它(这是我想要的)但 parent 也没有看到它。

我如何确保信号由 child 发出并由 parent 照料?

最佳答案

manual for raise(3)似乎表明它专门将信号发送给调用线程,而不是整个进程,因此一个线程引发的信号不会被另一个线程看到:

The raise() function sends a signal to the calling process or thread. In a single-threaded program it is equivalent to

      kill(getpid(), sig);

In a multithreaded program it is equivalent to

      pthread_kill(pthread_self(), sig);

raise(SIGABRT) 显式更改为 kill(getpid(), SIGABRT) 似乎做你想做的,并将信号发送到整个过程,所以它被一些没有阻止它的线程捕获。

关于c++ - 子线程引发它忽略的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44520841/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com