情境:
我有一个控制台应用程序(consoleApp
),其中我使用另一个dll的导出函数(exported_func
)。在那个函数中,我已经开始了一个新的无限线程。这是代码 -
EXPERIMENTAL_API int exported_func(void)
{
auto f = []() {
while (true)
{
cout << "H";
this_thread::sleep_for(100ms);
}
return 1;
};
async_res.value = async(launch::async, f);
return 1;
}
现在,从我调用此函数的main()
函数开始,之后我在main函数中启动了一个无限循环。这是代码 -
int main()
{
exported_func();
while (true)
{
cout << "L";
this_thread::sleep_for(100ms);
}
return 0;
}
问题:
问题是,如果我想通过单击控制台的关闭按钮来关闭我的控制台应用程序,则关闭应用程序需要10秒钟。
此外,如果我使用CreateChildProcess
创建一个进程(对于consoleApp.exe),则该进程无法使用ExitProcess
终止。
但是如果我从main函数(来自consoleApp)创建线程(async),那么它会立即关闭,并且可以使用ExitProcess
终止。
任何人都可以解释一下这里发生的事情吗?
注意:我正在使用Visual Studio 17,因此使用visual c ++ v141构建工具。
答案 0 :(得分:1)
点击关闭按钮并致电ExitProcess
都会导致......呼叫ExitProcess
。
ExitProcess
所做的部分工作是使用DLL_PROCESS_DETACH
为每个加载的DLL调用DLL入口点函数。
VC ++运行时的DLL入口点(_DllMainCRTStartup
)在收到DLL_PROCESS_DETACH
时所做的部分工作是调用DLL的全局变量的析构函数。
由std::future
返回的std::async
的析构函数阻塞,直到共享状态变为准备状态 - 它从未执行过,因为1)您的函数没有返回,2){{1}无论如何强制终止运行该函数的线程。
EXE are handled differently中的全局对象,至少对于运行时库的更新版本,在调用ExitProcess
时不会调用它们的析构函数。