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.csdn.net/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 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::instance().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.
2.use a static instance inside dll/dylib, construct it after any constructor of static instances. When the instance destructor is called, stop threads.