【发布时间】:2016-04-04 16:59:27
【问题描述】:
我正在开发一个与 C API 兼容的库。
在库中会有一个对象的全局实例,它的成员是std::thread。似乎由于某种原因,当main 返回并调用exit() 时,线程被自动杀死/终止。如果代码在同一个项目中使用(直接在可执行文件中而不是通过库),则不会发生这种情况。
我希望以下示例在无限循环中运行:while(1) {...} 和 thread.join() 应该相互阻塞。与库一起使用时不会,当调用 CThread 的析构函数时,线程似乎已经被杀死/完成。我在这里错过了什么?
CThread.h
#ifndef CTHREAD_H
#define CTHREAD_H
#ifdef EXPORT_C_THREAD
# define EXPORT_CTHREAD __declspec(dllexport) __cdecl
#else
# define EXPORT_CTHREAD __declspec(dllimport) __cdecl
#endif
void EXPORT_CTHREAD testFunc();
#endif
CThread.cpp
#include "CThread.h"
#include <thread>
#include <memory>
class CThread
{
std::thread m_thread;
void infiniteLoop()
{
while (1) {
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
}
public:
CThread()
{
m_thread = std::thread(&CThread::infiniteLoop, this);
}
~CThread()
{
m_thread.join();
}
};
std::unique_ptr<CThread> cthread;
void testFunc()
{
cthread = std::make_unique<CThread>();
}
main.cpp(这是在另一个项目中。我正在链接到上面的库。)
#include "CThread.h"
int main()
{
testFunc();
return 0;
}
更新
按照建议,我尝试在DLL_PROCESS_ATTACH 期间初始化DllMain() 函数中的cthread 对象,并在DLL_PROCESS_DETACH 期间解除分配。由于DllMain()-函数将获取加载程序锁,我必须稍后初始化线程。然而,和以前一样,当DLL_PROCESS_DETACH 被“调用”时,线程已经中止了。 DLL_THREAD_DETACH 不会在退出时被调用。
还有什么建议吗?谢谢!
【问题讨论】:
-
这不是
C代码所以请删除c标签。 -
因为它是库的 C 接口,所以我认为没问题。现在已删除。
-
Visual Studio 2013
-
DLL 调用不导出 C++ 语义。使用 fdwReason = DLL_PROCESS_DETACH 查看 DllMain 进行 DLL 清理。
-
@RyanBemrose 我没有导出任何 C++ 语义(只是一个 C 函数)。在线程中止之前不会分离 DLL。当线程中止时,全局实例 cthread 仍然可用。您能否给我一些关于 DLL 清理的附加信息/cmets?谢谢!
标签: c++ visual-studio c++11 dll std