multithread and static instances inside dll/dylib

本文探讨了在MacOS环境下使用线程池时遇到的问题,特别是在动态链接库(dylib)中使用线程池可能导致的静态实例析构期间出现的竞态条件。文章通过一个具体的例子说明了如何避免在析构过程中因线程未正确停止而导致的崩溃,并提出了两种解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

In macosx, it seems that subthreads won't terminate until after any function which is registered to the api atexit is done. see this: https://blog.youkuaiyun.com/newmandirl/article/details/80079989


When you're using any threadpool in dll/dylib, such as QThreadPool, I think you should be very careful.

Personal experience:

simple code below:

dylibModule() {
	// ..
	init_static_instances();
	// ..
	startThreadPool();
	// ..
}

~dylibModule() {
	// ..
	// may not need to call uninit_static_instances because system will automatically call ~xx() as they are static instances
	stopThreadPool();
	// ..
}

Let me tell you what will happen in this situation:

        supposing that there is a qmutex you will use in a static instance TestA:

class TestA() {
public:
	void test() {
		mutex.lock();
		//..
		mutex.unlock();
	}
	static TestA & getInstance() { static TestA instance; return instance; };
private:
	QMutex mutex;
}

there is a possibility in a time line:

// --- main-thread --->
dlclose(dylibModule);
instance::~TestA();// destruct TestA static instance
//.. destruct other static instances
~dylibModule();
// .. do something in ~dylibModule()
stopThreadPool();
// .. do something in ~dylibModule()
// <--- main-thread ---

// --- sub-thread --->// main-thread is waiting for other sub-threads because of stopThreadPool().
TestA::getInstance().test();
// crash in mutex.lock()!!!!!!!!!!!!!
// <--- sub-thread ---

Personal handler:

Make sure that threads are stopped before the static instances are destroyed. In this way we can avoid accessing invalid memory.

There are tow methods:

1.stop threads before FreeLibrary()/dlclose() outside dll/dylib. I think this method would be better than method2.

2.use a static instance inside dll/dylib, construct it after any constructor of static instances. When the instance destructor is called, stop threads. This method may still have a risk: static instances in other dll/dylib are already destroyed, but some sub-thread in this dll/dylib is still running and trying to access those instances.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值