【问题标题】:How to start a thread in DLLMain?如何在 DLLMain 中启动线程?
【发布时间】:2017-05-12 06:55:28
【问题描述】:

如何在 DLLMain 中启动线程意味着 std :: thread - 从根本上说。 No 表示 WinApi,STL 表示。当我在流程中运行该函数时,我会从该 DLL 调用应用程序崩溃。提前谢谢你。

此代码获取文件 (exe) 的哈希值并将其写入文件。 (* 。文本文件)。但是应用程序崩溃

void initialize()
{
    string buffer;
    thread t(calclulateHash, ref(buffer));
    t.detach();
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            initialize();
            break;
        }
    }
    return true;
}

【问题讨论】:

  • 这些“意味着/没有手段/意味着”的东西是什么?

标签: c++ multithreading c++11 dll dllmain


【解决方案1】:

1 DllMain -> 2 新线程 -> 3 再次使用 DLL_THREAD_ATTACH 调用 DllMain -> 4 不检查,所以再次新线程 -> 5 再次使用 DLL_THREAD_ATTACH 调用 DllMain;就像第 3 步一样;

【讨论】:

  • 他实际上得到了检查,但是 1 DllMain -> 2 新线程 -> 3 再次使用 DLL_THREAD_ATTACH 调用 DllMain 是不可能的
  • @Swift 是的,有可能,前提是允许DLL_PROCESS_ATTACH 先退出。
【解决方案2】:

DllMain() 有一些限制。

您不应该在 DllMain 中进行任何阻塞调用,因为它是从操作系统加载程序调用的。锁定加载程序可能会阻止某些线程启动,并且通常会导致坏事。任何形式的锁定。如果您尝试获取当前由需要 OS 加载程序锁的线程持有的锁(您在执行时持有该锁),在最佳情况下您将死锁。不允许启动线程,因为当您启动线程时..您通过操作系统加载程序再次调用此 DllMain,但现在使用 DLL_THREAD_ATTACH 参数。导致同样死锁或非法并发访问该模块未初始化的内存。

明确禁止调用 LoadLibrary/LoadLibraryEx,因为这需要操作系统加载程序锁定。其他调用 kernel32 没问题,你不能调用 User32。并且不要使用 CRT 内存管理(除非你是静态链接的),任何调用动态 C 运行时的东西——改用 HeapAlloc 和类似的 API。否则,您将调用 SxS 运行时库。您也无法读取注册表。任何跨二进制调用都是 UB,您调用的二进制可能尚未初始化或未被使用。

祝你有美好的一天。

【讨论】:

  • 那么有可能在 DLLMain 中使用 std::thread 吗?或者是 CreateThread (windows api) 的唯一选择
  • @user230568 你不能在那里创建线程。 CreateThread 是 kernel32 ,但你不能导致操作系统加载程序的递归。制作一个导出函数来执行额外的初始化,从您的应用程序中调用它,相当多的 API DLL 都这样做。如果需要,请使 DLL 的其他功能在该调用之前无法工作。或者,更好的是,尝试模拟在第一次调用 DLL 时创建的单例
  • std::thread 并不神奇。下面,它使用操作系统线程支持,所以它也是被禁止的。
  • @Euro Micelli 我猜,对于在不了解它如何工作的情况下使用它的人来说,它是神奇的。你知道,成功的先进技术......
  • @Swift 见Does creating a thread from DllMain deadlock or doesn’t it?。在DllMain() 中单独调用CreateThread() 是安全的(只是不推荐),但在线程上等待是不安全的。只要调用CreateThread()DllMain()退出,就不会发生死锁。
猜你喜欢
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 2010-12-25
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多