gpt4 book ai didi

使用 future 、 promise 、分离线程时出现 C++ 错误 C2893、C2780、C2672

转载 作者:行者123 更新时间:2023-12-03 07:52:12 28 4
gpt4 key购买 nike

我有一个名为 cApp 的类.
我要跑CheckProcessList()在后台直到程序终止。所以我想,好吧,让我们在一个独立的线程中运行它,直到 ~cApp() .我在 CheckProcessList() 中创建了一个 bool 值以跳出循环。 .在 ~cApp我将 bool 值设置为 true m_bTerminateThread = true爆发,等待 promise m_barrierFuture->wait()该线程已结束执行。爆发后我 promise barrier.set_value()线程现在正在结束执行。现在~cApp可以完成执行。或者至少这是我对我想要实现的目标以及如何去做的理解。好吧,这是不对的,因为我得到了编译器错误。
为什么它首先要检查线程是否完成?因为程序在终止时在运行时中断并且线程在那个时刻位于GetProcId()。 .如果它在终止时处于休眠状态,则程序不会中断。
我在 msdn 和 stackoverflow 中搜索了答案,但我没有从中得到任何我能理解的东西。我正在使用 VS2019 和 C++14。提前谢谢你们。

cApp.h

#pragma once
#include "wx/wx.h"
#include "cMain.h"
#include <thread>
#include <future>

class cApp
: public wxApp
{
public:
cApp();
~cApp();

virtual bool OnInit();

private:
// supposed to run in a detached thread
// until the program terminates
void CheckProcessList(std::promise<void> barrier);

// Checks whether or not the game processes are running
// this thread runs asynchronous until ~cApp
std::thread* m_tCheckProcList;
// used in thread "m_tCheckProcList"
// if set to true the thread terminates asap
bool m_bTerminateThread;
// used in thread "m_tCheckProcList"
// in ~cApp this future waits for the promise that the thread has finished
std::future<void>* m_barrierFuture;

// Dark Souls 3 Processname
const wchar_t* m_ds3Name;
// Need for Speed: Most Wanted Processname
const wchar_t* m_nfsmwName;
// Serious Sam: The Second Encounter Processname
const wchar_t* m_sstseName;

const wxString* m_frameTitle;
const wxSize* m_frameSize;

cMain* m_mainFrame;
};

cApp.cpp

#include "cApp.h"

wxIMPLEMENT_APP(cApp);

cApp::cApp()
{
m_ds3Name = L"DarkSoulsIII.exe";
m_sstseName = L"SeriousSam.exe";
m_nfsmwName = L"speed.exe";
m_frameTitle = new wxString("DeltaWin");
m_frameSize = new wxSize(600, 450);
m_bTerminateThread = false;
m_mainFrame = nullptr;
m_tCheckProcList = nullptr;
m_barrierFuture = nullptr;
}

cApp::~cApp()
{
// send the thread the "signal" to finish asap
m_bTerminateThread = true;
// wait for thread "m_tCheckProcList" to finish execution
m_barrierFuture->wait();
}

bool cApp::OnInit()
{
// create main top-level window
m_mainFrame = new cMain(*m_frameTitle, wxDefaultPosition, *m_frameSize);
m_mainFrame->Show();

// create barrier and instantiate the future for it
std::promise<void> barrier;
m_barrierFuture = new std::future<void>(barrier.get_future());

// start checking for running game processes in asynchronous thread
m_tCheckProcList = new std::thread(&cApp::CheckProcessList, std::move(barrier));
m_tCheckProcList->detach();

return true;
}

void cApp::CheckProcessList(std::promise<void> barrier)
{
while (!m_bTerminateThread)
{
// Dark Souls 3
if (GetProcId(m_ds3Name) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::DarkSouls3);
else
m_mainFrame->MenuItemEnable(true, menuItem::DarkSouls3);

// Need for Speed: Most Wanted
if (GetProcId(m_nfsmwName) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::NFSMostWanted);
else
m_mainFrame->MenuItemEnable(true, menuItem::NFSMostWanted);

// Serious Sam: The Second Encounter
if (GetProcId(m_sstseName) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::SeriousSamTSE);
else
m_mainFrame->MenuItemEnable(true, menuItem::SeriousSamTSE);

// Sleep 1.5s to save resources
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}
// set the promise that the thread has ended execution
barrier.set_value();
}
编辑:
程序在 ~cApp 之后终止.因此,我认为在这种特殊情况下,我不必 delete所有这些内存,因为操作系统会照顾它。
编辑2:

C2893: Failed to specialize function template"unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...)noexcept()".

C2780: "unknown-type std::invoke(_Callable &&) noexcept()":expects 1 arguments - 2 provided

C2672: "invoke": no matching overloaded function found

最佳答案

m_tCheckProcList = new std::thread(&cApp::CheckProcessList, std::move(barrier));我不知道您的错误与哪一行有关(您没有显示此内容),但我怀疑至少上述陈述是错误的。
如果将线程过程的地址传递给 std::thread构造函数并且这个过程是一个非静态成员函数后面的下一个参数必须是你引用的对象的地址(毕竟一个非静态成员函数必须有一个实例代表它被调用的)。 std::promise不是包含这种函数指针类型的类型&cApp::CheckProcessList所以这行不通。
如果您想将该线程与创建它的对象相关联,通常此类调用如下所示:

std::thread(&cApp::CheckProcessList, this, ...
或者可以使用静态成员函数或自由函数。
cApp::CheckProcessList(std::promise<void> barrier)代码中的另一个问题是按值将 promise 对象传递给线程函数。这意味着 Promise 的本地拷贝,但 Promise 不可复制。
您也不能通过引用或指针传递它!因为 barrierOnInit() 的局部变量方法,并且一旦该方法完成,该变量无论如何都会被破坏 - 底层的分离线程将与无效的堆栈帧混淆或导致任何类型的未定义行为。也许你可以制作 barrier数据成员或重新考虑您的设计。
在处理分离的线程时要非常小心。当使用不当时,它们充满了陷阱。

关于使用 future 、 promise 、分离线程时出现 C++ 错误 C2893、C2780、C2672,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65634934/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com