【问题标题】:Thread created by static object deleted before DTor?由静态对象创建的线程在 DTor 之前删除?
【发布时间】:2017-08-23 22:59:42
【问题描述】:

我的代码中有以下类。 也就是说,CTor中有一个静态对象(singletone)创建线程,当它的DTor被调用时,它在这个线程的上下文中有一些工作要做(DTor给线程放了一些工作)。

我面临的问题是,当调用 B 的 DTor 时,进程中没有其他线程在运行 - 似乎该线程在调用 B 类的析构函数之前被进程清理杀死。

有人知道为什么会这样吗?以及如何避免?

UPD:仅当从 DLL 创建 Singleton 时才会出现问题。从同一个可执行文件创建 Singleton 时,一切正常。

我正在使用 VS2017

  Singleton.dll (A.h + A.cpp)

A.h --> 

#pragma once
#include <thread>

class __declspec(dllexport) A
{
public:
    static A* instance();
    A();
    ~A();
private:
    bool stopFlag;
    std::thread mThread;
};

A.cpp

#include "stdafx.h"
#include <thread>
#include "A.h"

using namespace std;

    A::A()
    {
        mThread = std::thread([this] { while (stopFlag == false) {  } });
    }
    A::~A()
    {
        stopFlag = true;
        mThread.join();
    }

A* A::instance()
{
    static A self;
    return &self;
}

================================================ ===================================
使用 DLL 的可执行文件 main.cpp

#include "stdafx.h"
#include "A.h"


int main()
{
    auto a = A::instance();
    return 0;
}

更新了可编译的代码。现在如果你把前两个文件编译成DLL,然后在A的析构函数中放断点,你会看到那个带lambda函数的线程不存在......

更新:找到了 myslef 的答案。在 Windows 中,当所有线程都已清理完毕时,DLL 中的静态对象会在最后一点被卸载 https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx

【问题讨论】:

标签: c++ multithreading singleton std destructor


【解决方案1】:

找到了myslef的答案。在 Windows 中,当所有线程都已清理干净时,DLL 中的静态对象会在最后一点被卸载 https://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx

【讨论】:

  • 您似乎想干净地控制线程关闭,您是否为此制定了解决方案?
  • 不幸的是,没有。问题是线程是从 DLL 静态对象创建的。该对象在进程已清理其所有线程后被破坏。我找到了两种干净但不舒适的解决方案,以及一种舒适但肮脏的解决方案
  • 1) 清理 - 创建一个 done() 函数,lib 的用户应该在进程结束之前调用它。在 done() 函数中杀死一个线程。 2) Clean - 用户可以将您的对象包装在它自己的对象中,并且用户的对象应该在其析构函数中调用 done() 函数 3) Dirty - 不在乎 - 进程正在完成,只是让它杀死所有使用的资源(在我的万一它会起作用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 2018-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
相关资源
最近更新 更多