我有一个带有用户定义析构函数的类。如果类最初被实例化,然后在程序运行时发出 SIGINT(在 unix 中使用 CTRL+C),析构函数会被调用吗? SIGSTP(unix 中的 CTRL + Z)的行为是什么?
不会,默认情况下,大多数信号都会导致程序立即异常退出。
但是,您可以轻松更改大多数信号的默认行为。
此代码显示如何使信号正常退出程序,包括调用所有常用的析构函数:
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <cstring>
#include <atomic>
std::atomic<bool> quit(false); // signal flag
void got_signal(int)
{
// Signal handler function.
// Set the flag and return.
// Never do real work inside this function.
// See also: man 7 signal-safety
quit.store(true);
}
class Foo
{
public:
~Foo() { std::cout << "destructor\n"; }
};
int main(void)
{
struct sigaction sa;
memset( &sa, 0, sizeof(sa) );
sa.sa_handler = got_signal;
sigfillset(&sa.sa_mask);
sigaction(SIGINT,&sa,NULL);
Foo foo; // needs destruction before exit
while (true)
{
// do real work here...
sleep(1);
if( quit.load() ) break; // exit normally after SIGINT
}
return 0;
}
如果运行该程序并按 Control-C,您应该会看到打印出“析构函数”一词。
请注意,除了设置标志并安静地返回之外,您的信号处理函数 (got_signal) 应该很少做任何工作,除非您真的知道自己在做什么。也可以看看:https://man7.org/linux/man-pages/man7/signal-safety.7.html https://man7.org/linux/man-pages/man7/signal-safety.7.html
大多数信号都是可捕获的,如上所示,但 SIGKILL 除外,您无法控制它,因为 SIGKILL 是终止失控进程的最后手段,而不是允许用户冻结进程的 SIGSTOP。请注意,如果需要,您可以捕获 SIGTSTP (control-Z),但如果您对信号唯一感兴趣的是析构函数行为,则不需要这样做,因为最终在 control-Z 之后,进程将被唤醒,将继续运行,并且将正常退出,并且所有析构函数都有效。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)