c++ - 在 DLL 中运行的工作线程在应用程序关闭时被杀死,然后才能正常关闭它们

标签 c++ windows multithreading c++11 dll

出于某种原因,我需要在 .dll 中有一个全局对象,它管理一个 std::thread。它是通过以下方式实现的:

#include "Header.h"
#include <thread>
#include <condition_variable>
#include <mutex>

class Foo
    {
public:
    Foo () : m_closeThread (false)
        {
        m_thread = std::thread (&Foo::ThreadProc, this);
        }

    ~Foo ()
        {
            {
            std::unique_lock<std::mutex> lock (m_mutex);
            m_closeThread = true;
            }

        m_cv.notify_one ();
        m_thread.join ();
        }

private:
    void ThreadProc ()
        {
        while (true)
            {
            std::unique_lock<std::mutex> lock (m_mutex);
            m_cv.wait (lock, [this] () { return m_closeThread; });
            if (m_closeThread)
                break;
            }
        }

private:
    bool m_closeThread;
    std::thread m_thread;
    std::condition_variable m_cv;
    std::mutex m_mutex;
    };

Foo& GetFoo ()
    {
    static Foo foo;
    return foo;
    }

extern "C" void Function ()
    {
    auto& foo = GetFoo ();
    }

但是,当应用程序关闭时, ~Foo 执行之前,.dll 的所有工作线程都会被杀死,或者作为输出窗口MSVS2015 说:

The thread 0x1040 has exited with code 0 (0x0).

并且,由于这个事实(Source0Source1),如果使用 Windows 7(在 Windows 上不阻塞),应用程序会阻塞 m_cv.notify_one (); 调用8 及以上)。

事实上,它在一个特定版本的 Windows 上阻塞,而不在其他版本上阻塞,这让我认为,某种 UB 是罪魁祸首(例如 DLL 卸载排序相关问题,因为如果这样的话,这样的问题是不可重现的对象不在 .dll 中),但我想不出解决方案,它允许我优雅地关闭线程,同时让对象成为全局对象(因为,需要进行主要的应用程序重组,使其不是全局的)。

那么,能否在线程被 Windows 平台杀死之前优雅地关闭线程?

旁注 0:

为了示例的完整性,

这是 DLLMain:

#include <Windows.h>

BOOL APIENTRY DllMain (HMODULE, DWORD, LPVOID) { return TRUE; }

这是 .dll 的 header :

#pragma once
extern "C" void Function ();

这是控制台应用程序,使用上述 .dll:

#include "..\Test\Header.h"
#include <chrono>
#include <thread>

int main ()
    {
    Function ();
    using namespace std::chrono_literals;
    std::this_thread::sleep_for (2s);
    }

旁注 1:

我目前最多只能使用 C++11(或者 MSVS 2015 中存在的任何功能)。

最佳答案

WinMain 返回时,运行时调用 ExitProcess .要做的第一件事是“1. 进程中的所有线程,除了调用线程,在没有收到 DLL_THREAD_DETACH 通知的情况下终止它们的执行。”

关于c++ - 在 DLL 中运行的工作线程在应用程序关闭时被杀死,然后才能正常关闭它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54444387/

相关文章:

c++ - 模拟器 c++ 的 GUI 选项

c++ - Main 无法调用函数 : function was not declared in this scope

ios - 在不同的线程中访问 Realm 和过滤器结果

c++ - 使用构造函数参数将仿函数传递给 std::thread。是否可以?

c++ - SSE 64 位寄存器

c++ - image.convertTo 并不总是有效

c++ - LDAP函数中有没有不使用ldap_search获取用户信息的函数?

php - 如何从源文件构建 WINCACHE .DLL?

.net - Windows 临时文件行为 - 它们是否被系统删除?

c++ - std::thread 构造函数如何检测右值引用?