C++ 如何安全地删除ATL DLL中的std::thread

C++ 如何安全地删除ATL DLL中的std::thread,c++,multithreading,atl,stdthread,C++,Multithreading,Atl,Stdthread,我编写了一个ATL DLL,但我在运行asyn方法时遇到了std::thread的问题。我实现了异步执行操作的方法。当客户端试图删除线程已在其中完成的对象类时,就会出现问题 这是我的代码: STDMETHODIMP CQRCodeGenerator::GenerateAsync(QRCodeTypeEnum QRCodeType, QRCodeFormatEnum QRCodeFormat, LONG QRCodePx, BSTR ImageFile) { if (ImageFile == n

我编写了一个ATL DLL,但我在运行
asyn
方法时遇到了
std::thread
的问题。我实现了异步执行操作的方法。当客户端试图删除线程已在其中完成的对象类时,就会出现问题

这是我的代码:

STDMETHODIMP CQRCodeGenerator::GenerateAsync(QRCodeTypeEnum QRCodeType, QRCodeFormatEnum QRCodeFormat, LONG QRCodePx, BSTR ImageFile)
{

if (ImageFile == nullptr) ImageFile = L"";

//stack to log file
OPFHelper::add_execute_method(this, L"CQRCodeGenerator::GenerateAsync",
    std::vector<std::wstring>{OPFHelper::ConvertToWSting((LONG)QRCodeType),
    OPFHelper::ConvertToWSting((LONG)QRCodeFormat), OPFHelper::ConvertToWSting((LONG)QRCodePx), ImageFile});

t = std::thread(&CQRCodeGenerator::run, this, QRCodeType, QRCodeFormat, QRCodePx, ImageFile);
return S_OK;
}

void CQRCodeGenerator::run(enum QRCodeTypeEnum QRCodeType, enum QRCodeFormatEnum QRCodeFormat, LONG QRCodePx, BSTR ImageFile)
{

 ......

Fire_OnGenerate(this,ImageFile, _pQRCode, _pInvoiceID, _pQRCodeMD5, _pKS,nullptr);
}   
STDMETHODIMP CQRCodeGenerator::GenerateAsync(QRCodeTypeEnum QRCodeType、QRCodeFormatEnum QRCodeFormat、LONG QRCodePx、BSTR ImageFile)
{
如果(ImageFile==nullptr)ImageFile=L“”;
//堆栈到日志文件
OPFHelper::add_execute_方法(这是L“CQRCodeGenerator::GenerateAsync”,
std::vector{OPFHelper::ConvertToWSting((长)QRCodeType),
OPFHelper::ConvertToWSting((长)QRCodeFormat),OPFHelper::ConvertToWSting((长)QRCodePx),ImageFile});
t=std::thread(&CQRCodeGenerator::run,this,QRCodeType,QRCodeFormat,QRCodePx,ImageFile);
返回S_OK;
}
void CQRCodeGenerator::run(枚举QRCodeTypeEnum QRCodeType、枚举QRCodeFormatEnum QRCodeFormat、长QRCodePx、BSTR图像文件)
{
......
Fire_OnGenerate(this,ImageFile,_pQRCode,_pInvoiceID,_pQRCodeMD5,_pKS,nullptr);
}   
  • std::thread
    .h
    文件中声明
  • 当我接收到事件并尝试删除obj
    QRCodeGenerator
    时,我得到错误
  • 我知道这是删除内存线程的问题,因为我执行了同步函数
    Generate
    ,但没有给出错误


    但我不知道如何删除此线程并检测
    Client
    何时想要删除obj。第二件事是它无法理解为什么当线程助手不再工作时释放内存会出现问题。

    在销毁线程之前调用
    std::thread::join()
    还是
    detach()
    ?否则,
    std::thread
    析构函数应该触发
    terminate()
    并中止程序

    例如,如果某个对象拥有该线程(正如“客户端试图删除线程已经完成的对象类”所建议的那样),该对象可能会在其析构函数中调用
    t.join()


    还要注意的是,您不应该破坏在运行线程范围内调用的
    Fire\u OnGenerate
    中的对象。因此,您基本上会销毁一个仍在运行的线程(它只能在
    Fire\u OnGenerate
    返回后才能完成)。

    在销毁线程之前调用
    std::thread::join()
    还是
    detach()
    ?否则,
    std::thread
    析构函数应该触发
    terminate()
    并中止程序

    例如,如果某个对象拥有该线程(正如“客户端试图删除线程已经完成的对象类”所建议的那样),该对象可能会在其析构函数中调用
    t.join()


    还要注意的是,您不应该破坏在运行线程范围内调用的
    Fire\u OnGenerate
    中的对象。因此,您基本上可以销毁一个仍在运行的线程(它只能在
    Fire\u OnGenerate
    返回后才能完成)。

    您可以在QRCodeGenerator的析构函数中执行某些操作,对吗?@TonyJ对,但是which和怎么办?客户端销毁obj时调用which方法?HRESULT FinalConstruct()/void FinalRelease()?然后呢?t、 join()?我不熟悉FinalConstruct()/FinalRelease(),但如果您编写了一个函数,在线程未完成时调用t.join(),则可以从FinalConstruct()/FinalRelease()和Destructor调用它。或者,您可以将CQRCodeGenerator重构为一个包装类,这样线程就不会与之耦合。@TonyJ感谢您的建议!你可以在QRCodeGenerator的析构函数中做点什么,对吗?@TonyJ,对,但是whitch和怎么做?客户端销毁obj时调用which方法?HRESULT FinalConstruct()/void FinalRelease()?然后呢?t、 join()?我不熟悉FinalConstruct()/FinalRelease(),但如果您编写了一个函数,在线程未完成时调用t.join(),则可以从FinalConstruct()/FinalRelease()和Destructor调用它。或者,您可以将CQRCodeGenerator重构为一个包装类,这样线程就不会与之耦合。@TonyJ感谢您的建议!我说的是事件将再次发生的情况。那么,我必须在ATL类中的何处添加t.join()?HRESULT FinalConstruct()?无效最终释放?我不知道当客户端尝试销毁obj时会调用whitch方法。我指的是事件返回OnGenerate的情况。那么,我必须在ATL类中的何处添加t.join()?HRESULT FinalConstruct()?无效最终释放?我不知道当客户端尝试销毁obj时调用了whitch方法。