多个线程调用exit()时的安全静态析构函数

时间:2014-11-03 20:08:18

标签: c++ multithreading mutex exit

当多个(Posix)线程并行调用exit()时,如何安全地删除静态C ++对象?

在我的CentOS6环境中exit()执行atexit(或on_exit)清理处理程序,通过调用fct[--cnt]()之类的内容cnt处理程序注册。当多个线程同时调用exit()时,我们在未受保护的--cnt操作中遇到竞争条件,并且可能会多次跳过或调用一些处理程序(导致偶尔崩溃)。 那么我怎样才能确保只有一个exit()调用线程进行清理而其他所有线程都停止了?请注意,将pthread_mutex_lock()插入清理处理程序没有帮助,因为可能会跳过此处理程序...

不幸的是我无法避免多个线程调用exit(),因为我的用户将编写代码(我正在为他们提供一个库)。

寻找安全的想法,谢谢!

2 个答案:

答案 0 :(得分:1)

没有可移植的方法来处理对exit()的多次调用 - 因为它是未定义的(行为)在这种情况下会发生什么。

但是,对于某些特定平台,您可能会找到一种方法。对于"多次调用的一种通用解决方案"是在你的静态对象中有一个标志,比如"我已经被破坏了#34;。像往常一样,您可以在模板中隐藏它:

template <typename T> class StaticExitHandled {
public:
    std::unique_ptr<T> t_;
    ~StaticExitHandled() { t_.release(); }
};

现在只记得使用此模板声明所有静态对象。这只是它的核心,根据您的口味添加铃声和口哨声。而且,而不是std :: unique_ptr&lt;&gt;你可以使用boost :: optional&lt;&gt;或者其他一些东西。

我不认为有一个通用的解决方案,而且根本没有打电话#34;

实际上,我建议不要在多线程环境中使用非平凡的静态对象。因此,只有静态POD和具有严格约束的析构函数的对象(取决于在您的环境中此时安全做什么 - 即在大多数环境中关闭文件句柄是正常的。)

答案 1 :(得分:0)

如果你正在使用gcc,你可以使用下面的代码来定义清理程序:

void __attribute__ ((destructor)) my_fini(void);

如果这没有解决您的问题,如何定义具有静态持续时间的单个对象,其析构函数将负责您的清理?