我有一个程序在启动时创建一个线程(我使用C ++ Boost库来创建线程)。在主程序中,我已将我的清理功能注册为。
atexit(cleanExit)
// Trap some signals for a clean exit.
signal(SIGQUIT, signalled)
signal(SIGABRT, signalled)
signal(SIGTERM, signalled)
signal(SIGINT, signalled)
static void signalled(int signal)
{
exit(signal)
}
static void cleanExit(void)
{
thread->interrupt();
thread->join();
}
正如你在干净退出过程中看到的那样,我打断线程,然后在这里等待(在主进程中),以便线程清理它的东西。当我调用thread->中断时,我的线程被中断,我做了线程cleanUp的东西。直到这里一切顺利,没有问题。
但是当我在线程中调用清理函数时会出现问题。在清理功能中,我将一些状态发送回服务器,因为我已经创建了一个实用程序函数,在这个实用程序函数中,我正在访问类的“const static string”成员。问题是当我访问这个const静态字符串时,我的应用程序被卡住了。我已经检查了strace,我得到了Seg Fault。但是当我将这个“const static string”改为“const string”时,我的清理工作顺利进行。
问 一旦程序终止,C ++“const static”的行为是什么。他们在调用退出时会放弃(在上面的案例中可以看到)或对此行为的任何想法。
这是线程处理函数。正如我上面提到的一个Boost线程。
try {
while ( true ) {
// Do your job here.
// 1: We can be interrupted.
boost::this_thread::interruption_point();
}
}
catch (boost::thread_interrupted const& )
{
// Before exiting we need to process all request messages in the queue
completeAllWorkBeforeExiting();
}
当主程序调用thread->中断时,该线程将在#1处引发thread_interrupted异常,并且捕获此异常我正在进行清理工作。
答案 0 :(得分:2)
const
不会影响任何对象何时被销毁。
static
个对象按其创建顺序的相反顺序销毁。 atexit
实际上创建了一个匿名的static
对象,其中给定的函数作为析构函数。也就是说,static
对象析构函数和atexit
回调按照与构造/注册相反的顺序发生。
从信号处理程序调用{{1}}是完全不安全的。实际上允许所有信号处理程序设置一个标志,稍后由线程轮询。正如您所提到的,信号处理程序在中断时运行,因此可能会中断系统调用。它可能以绕过exit
多线程锁的方式中断malloc
,因为重入是在同一个线程上,而不是通常发生的不同。
因此,这是各种不可预测的行为的来源。在没有看到更多内容的情况下,我无法更具体地了解malloc
的效果,但它可能与更改对象的生命周期和/或每个对象实例化一次有关。