我遇到一种情况,我在DLL(节点本机模块)中有一个工作线程,它使用std::condition_variable
进行同步。当可执行文件退出时它只会杀死我的工作线程,因为它是一个节点本机模块,我无法访问DLLMain,所以我不知道即将关闭。
当我尝试通过notify_all()通知我(已杀死且因此不存在)的线程关闭时,该调用只会挂起(在Window 7上)或崩溃(Windows 10)。
经过一些研究后,我发现RTL内部使用了CONDITION_VARIABLE。我可以用这个小代码片段重现崩溃:
#include <Windows.h>
#include <thread>
#include <condition_variable>
#include <chrono>
std::mutex mutex;
std::condition_variable cond;
CONDITION_VARIABLE win_cond = CONDITION_VARIABLE_INIT;
CRITICAL_SECTION cs;
void worker() {
//std::unique_lock<decltype(mutex)> lock(mutex);
//cond.wait(lock);
EnterCriticalSection(&cs);
SleepConditionVariableCS(&win_cond, &cs, INFINITE);
LeaveCriticalSection(&cs);
}
int main()
{
InitializeCriticalSection(&cs);
std::thread thread(worker);
std::this_thread::sleep_for(std::chrono::seconds(1));
// Simulate DLL shutdown with lpReserved != null
::TerminateThread(thread.native_handle(), 0);
//cond.notify_all();
WakeAllConditionVariable(&win_cond); // crash
thread.join();
return 0;
}
我的问题是:
请注意,我想继续使用c ++标准库,因为此代码必须在Windows上的其他操作系统上运行。