在win32 DLL_PROCESS_DETACH下调用std :: thread :: join函数是否安全? [英] Is it safe to call std::thread::join function under win32 DLL_PROCESS_DETACH?

查看:288
本文介绍了在win32 DLL_PROCESS_DETACH下调用std :: thread :: join函数是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请查看下面的代码段//在 DLL 项目中单个 .cpp 单元下定义的这些代码块

----- ------------- DLL -------------------------



Please look at code snippet below // these code blocks defined under single .cpp unit in DLL project
------------------ DLL -------------------------

static std::thread sendMessageThread; // define as local static to cpp
//....//
bool  callFunction()
{
   /// Some simple code without spawning any thread or fibers
 }
void WINAPI OnEngineStart()
{
    sendMessageThread = std::thread(callFunction);
};

    BOOL WINAPI DllMain(HINSTANCE hDll, DWORD fdwReason, LPVOID lpvReserved)
    {
        switch (fdwReason)
        {
        case DLL_PROCESS_ATTACH:
            break;
        case DLL_PROCESS_DETACH:
            if (sendMessageThread.joinable())
            {
                sendMessageThread.join(); // is this safe?
            }
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        }

    return TRUE;
};





--------------------- ---------------- DLL --------------------------



如果加载DLL的进程调用OnEngineStart函数,那么每当它卸载DLL时(使用FreeLibrary WinAPI函数),它会等到sendMessageThread完成吗?并继续DLL卸载程序?



我尝试过:



我用这个DLL运行程序,程序永远不会崩溃和停止。但我找到了这些东西:

是否从DllMain死锁创建线程或不是吗? - The Old New Thing [ ^ ]

动态链接库最佳实践(Windows) [ ^ ]



------------------------------------- DLL --------------------------

If the process which loaded the DLL call OnEngineStart function then whenever it unloads the DLL(using FreeLibrary WinAPI function), will it wait until sendMessageThread gets finished? and continue with DLL unload procedure?

What I have tried:

I run the program with this DLL,program never crash and halt.But I found these stuff:
Does creating a thread from DllMain deadlock or doesn’t it? – The Old New Thing[^]
Dynamic-Link Library Best Practices (Windows)[^]

推荐答案

,您正在完成Raymond Chen在博客文章中所描述的内容。您正在等待DLL_PROCESS_DETACH中的线程。确保你理解'DLL通知被序列化'意味着什么。



我想我知道一种方法来证明为什么这是一个坏的想法...在sendMessageThread中添加一些代码,调用 getenv_s,_wgetenv_s [ ^ ]。还要向父进程添加一些代码以定期加载/卸载DLL。这最终会导致代码死锁。死锁的原因是CRT访问全局_ENV_LOCK并可能导致竞争条件。还有许多其他方案会导致死锁。



一种可能的解决方案是通过添加OnEngineStop线程消息来改变您的架构并在那里等待。 />


祝福,

-David Delaune
No, you are doing exactly what Raymond Chen describes in his blog entry. You are waiting for the thread in your DLL_PROCESS_DETACH. Make sure that you understand what 'DLL notifications are serialized' means.

I think I know a way to demonstrate why this is a bad idea... add some code in your sendMessageThread that calls getenv_s, _wgetenv_s[^]. Also add some code to your parent process to load/unload the DLL periodically. This should eventually cause your code to deadlock. The reason for the deadlock is that the CRT accesses a global _ENV_LOCK and will potentially cause a race condition. There are dozens of other scenarios that will cause a deadlock.

One possible solution is to change your architecture by adding a OnEngineStop thread message and do your waiting there.

Best Wishes,
-David Delaune


这篇关于在win32 DLL_PROCESS_DETACH下调用std :: thread :: join函数是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆