我的一个Linux项目使用大量共享库,这些共享库与dlopen/dlsym/dlclose
连接以获得模块化。出于线程安全的原因,我需要将全局变量(boost::mutex
)放在共享库之一中。显然,boost::mutex
有non-trivial destructor。 (甚至可以abort(3)
程序)。
我知道使用不可微分解的全局变量是一个坏主意,并且明确规定了forbid的某些准则来执行此类操作,但是我确实需要模块的全局互斥体。
添加全局boost::mutex
变量后,它在程序退出时崩溃。 (由于boost::mutex::lock()
的{{1}}而抛出EINVAL
)我假设共享库在main之后被调用,但是该互斥体已经被破坏。 (我认为,静态破坏命令会造成惨败。)
不幸的是,该程序非常复杂,我需要一种变通方法来按时完成工作。 挖掘了ctor / dtor的内容后,我发现此代码有效。
pthread_mutex_lock
然后,在共享库的#include <boost/aligned_storage.hpp>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/type_traits/alignment_of.hpp>
boost::aligned_storage<sizeof(boost::mutex), boost::alignment_of<boost::mutex>::value> gMutexStorage;
boost::mutex* gMutex = NULL;
__attribute__ ((constructor))
void MyModuleInit()
{
gMutex = new(reinterpret_cast<boost::mutex*>(gMutexStorage.address())) boost::mutex();
}
__attribute__ ((destructor))
void MyModuleUnInit()
{
gMutex->~mutex();
gMutex = NULL;
}
// global mutex use
extern "C" __attribute__ ((visibility("default")))
int SomeFunc(...)
{
boost::lock_guard<boost::mutex> guard(*gMutex);
....
}
节中注册的此MyModuleUnInit
函数(作为参考,在.fini_array
中注册的静态C ++变量的其他析构函数),在使用互斥量后调用该函数。 ,因此程序可以正常退出。
但是,我对这种互斥锁使用的安全性不满意。这些代码可以使用吗?如果没有,我该如何处理dlopen-ed共享库的static(global)变量?