多线程进程中的信号处理
Signal handling in mutlti-threaded process
我有一个在多线程进程中处理信号的基本问题。
在我的代码中,我从主线程创建了一个子线程,以侦听稍后将由主线程触发的SIGALRM
(使用timer_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;
}
预期结果
- 在主线程中,等待子线程终止
- 在子线程中,
SIGALRM
被捕获,返回 - 在主线程中,终止
观察结果
- 在主线程中,等待子线程终止
- 闹钟
其他信息:我使用的是g++(Debian 5.4.0-4)5.4.0 20160609。
您的run_something
线程在为该信号调用sigwait
之前取消阻止SIGALRM,但这是未定义的行为。sigwait
从挂起(即阻塞)信号集合中移除信号。
不要在你的线程中取消阻止,你会看到你期望的行为。
显示的代码没有为SIGARLM
设置任何信号处理程序。
因此,在接收信号时,操作系统会按照它应该做的去做,即调用SIGALRM
的默认操作,即终止进程。将"闹钟"打印到控制台是默认行为的一部分,BTW.
要解决此问题,请为SIGARLM
设置一个信号处理程序。这可以通过使用CCD_ 10以可移植的方式来实现。
也不要在多线程程序中使用sigprocmask()
,因为它的行为是未指定的。请改用pthread_sigmask()
。
更新:
我错过了代码调用sigwait()
…:}
在这种情况下,修复这些问题并不需要设置一个信号处理程序(它仍然可以解决问题,并且是有效的),而是按照pilcorow的回答所建议的那样做,即在调用sigwait()
(或sigwaitinfo()
)之前阻止信号。
此外由于上述原因,请确保使用pthread_sigmask()
而不是sigprocmask()
。
与问题无关:
我从主线程创建一个子线程
没有"子"线程这样的概念。创建之后,所有进程的线程都是同一级别上的"兄弟"。这包括使用main()
启动的初始线程。"主"线程通常是这样调用的,只是因为它的线程函数的名称:main
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 如何在信号处理程序和普通函数中对全局变量进行互斥读写操作
- 有可能在信号处理程序中设置promise吗
- 在信号处理程序中捕获C++未处理的异常并恢复应用程序
- 调试和自由执行中的信号处理
- 通过安装信号处理程序关闭多线程应用程序
- 将更高的优先级设置为 boost::asio 线程处理进程
- 为什么我的信号处理程序只执行一次?
- GTK C++:找不到信号处理程序 您是否使用 -rdynamic 进行了编译?
- C++ 在信号处理程序后继续执行
- 没有信号处理程序的POSIX定时器的目的是什么?
- 为什么这个信号处理程序不能捕获 SIGHUP 或 SIGQUIT?
- 如何在C++中使用 std::bind 函数作为信号处理程序?
- 在 C++17 中,是否未定义使用无锁原子学保护从信号处理程序传递的数据?
- 如何将信号处理程序添加为方法
- 窗口上信号处理程序的异步安全写入函数
- 子进程 c++ 的 Windows 控制台信号处理
- 用户空间和内核空间进程中的信号处理程序集
- 进程等待另一进程终止时的信号处理
- 多线程进程中的信号处理