问题
I'm trying to prevent multiple calls to a DLL initialization function by using a std::lock object.
While using a program like this on a stand alone program works:
#include <mutex>
std::mutex mtx;
void main(){
mtx.lock();
(...)
mtx.unlock()
}
This exact same code cannot get past the mtx.lock() when called on a DLL.
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
f_Init(VERSION_ID);
return TRUE;
}
//On another cpp file, a static library actually.
#include <mutex>
std::mutex mutex_state;
void f_Init(DWORD version){
//Acquire the state lock
mutex_state.lock(); //<-- Will NOT get past this line
(...)
mutex_state.unlock();
}
Why is it imposible to lock the mutex on this situation?
I'm currently using Microsoft Visual Studio 2013.
回答1:
The mutex is not needed. Access to DllMain
is serialized by the implementation.
Access to the entry point is serialized by the system on a process-wide basis. Threads in DllMain hold the loader lock so no additional DLLs can be dynamically loaded or initialized. -- DllMain Entry Point
Your code deadlocks deadlock when you enter DllMain
because you already hold locks. Trying to acquire additional locks while holding some unknown combination of locks is very, very likely to deadlock. You should never acquire any additional locks inside DllMain
.
Consider, for example, if some additional DLL needs to be attached to lock the mutex. Two DLL's cannot be attached at the same time, and your DLL is being attached. Locking a mutex for the first time may require allocating memory and allocating memory may require attaching DLL's -- so don't do that in DllMain.
By the way, these same painful restrictions apply to constructors and destructors for global objects.
来源:https://stackoverflow.com/questions/24601501/cannot-lock-a-c-11-stdmutex-on-a-dll