如果线程是从dll创建的,std :: async会阻止进程退出吗?

时间:2017-08-28 06:26:58

标签: c++ multithreading c++11

情境:

我有一个控制台应用程序(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构建工具。

1 个答案:

答案 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时不会调用它们的析构函数。