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.