关于 C++ std::thread 的疑问

2018-12-19 15:53:37 +08:00
 sky2017

偶然间在项目里遇到一个问题,问题是这样产生的:在 dll 里写了个类,这个类构造函数里初始化 std::thread 创建了个线程,然后将这个类设为全局变量,最后在一个 exe 里加载这个 dll 居然阻塞了主线程?? 这个问题查了好半天,后来发现用这样的步骤就可以重现。

1.在一个 DLL 里写一段代码:

class TestClass
{
public:
    TestClass()
    {
        m_thread = std::thread([] {});
    }
    ~TestClass()
    {
        if (m_thread.joinable())
        {
            m_thread.join();
        }
    }
protected:
private:
    std::thread m_thread;
};

创建一个空线程什么都不干

2.定义一个全局变量:

TestClass tc;

3.写个 exe 用 LoadLibrary 加载这个 dll:

HMODULE hModule = ::LoadLibrary(L"...");

然后就没有然后了,exe 会阻塞在 LoadLibrary()这一句。

如果把 TestClass 代码拷贝到 exe 里,然后设为全局变量则没有这个问题。 我是用 vs2015 测试的,可能是我用 std::thread 方法不对,但是有高手能分析一下原因吗?奇怪的是网上也搜不到答案。

4590 次点击
所在节点    C
27 条回复
zwh2698
2018-12-20 09:01:54 +08:00
另外不要 wait 也没事,简单黑中线程注入都是这么干的
ZouZhiZhang
2018-12-20 09:24:53 +08:00
@v2qwsdcv --whole-archive
ZouZhiZhang
2018-12-20 09:26:42 +08:00
dllmain 有锁,然后运行时初始化全局变量也在 dllmain,开线程会调用 dllmain 的 thread attach,几就死锁了…
macha
2018-12-20 10:08:14 +08:00
第一反应就是 dllmain 的 deadlock,没想到现在还有人讨论 Windows 的编程。
v2qwsdcv
2018-12-20 13:51:12 +08:00
@ZouZhiZhang 貌似不行啊 是不是我用错了
g++ --std=c++11 -fPIC -shared -o libdy.so -Wl,--whole-archive dynamic.o -Wl,--no-whole-archive
v2qwsdcv
2018-12-20 13:52:09 +08:00
@ZouZhiZhang 依然不能导出自定义类型的 全局变量。
inoki
2018-12-20 14:51:48 +08:00
看到两段构造,想到 obc

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/519019

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX