gpt4 book ai didi

c++ - 如何过早停止长时间运行的功能?

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

我正在研究一种绘图算法。为此,我从主GUI线程中的DAQ板上获取数据,然后将数据发送到工作线程进行处理,该工作线程发出带有新QImage的信号,该信号在图形用户界面中显示为图。问题在于函数,我们将其称为generateImage(),以计算和生成QImage会花费很长时间(约50-70毫秒,具体取决于数据长度),并且在此期间可能会到达另一组数据,这将需要工作线程从头开始重新计算情节。我希望generateImage()放弃计算,如果新数据仍在计算时到达,则从头开始重新计算。我的方法是设置一个成员 bool 变量,我们将其称为b_abort_,并在generateImage()return内部检查是否将其设置为true,在generateImage()外部始终将其设置为true,而我仅在调用generateImage()之前将其设置为false。
所有这些都在工作线程中发生,我将QObject子类化,并使用moveToThread()将其移至工作线程中。
开始计算的函数:

void WorkerThread::startCalc()
{
b_abort_ = false;
generateImage();
// if b_abort_ is set to true, generateImage() will return prematurely
if(b_abort_)
emit calcFinished();
else
b_abort_ = true;
}
进行所有计算并生成图像的函数:
void WorkerThread::generateImage()
{
/* Calculation of some parts */
for(int ii = 0; ii < Rawdata.length(); ++ii) // Starting main time consuming loop
{
if(b_abort_)
return;
/* Perform calculation for one data point from Rawdata */
}

// data calculation complete, now it's time to generate QImage
// before that I check if b_abort_ is set to true
if(b_abort_)
return;

for(int ii = 0; ii < CalculatedData.length(); ++ii) // plotting calculated data on QImage
{
if(b_abort_)
return;
/* plot one data point from CalculatedData vector */
}

// generation of QImage finished, time to send the signal
emit renderedPlot(image); // image is a QImage object
}
在我的工作线程中,我有一个插槽可从主GUI线程接收数据,它使用 Qt::QueuedConnection(默认)作为连接类型进行配置:
void WorkerThread::receiveData(QVector<double> data)
{
if(!b_abort_) // check if calculation is still running
{
QEventLoop loop;
connect(this, &WorkerThread::calcFinished, &loop, &QEventLoop::quit);
b_abort_ = true; // set it to true and wait for calculation to stop
loop.exec();
// start new calculation
RawData = data;
startClac();
}
else
{
RawData = data;
startClac();
}
}
当我在主GUI线程中使用此方法时, generateImage()函数将阻止所有事件循环,并且GUI冻结,这使我认为在单个线程(主GUI线程或辅助线程)中,一次只能运行一个函数因此 b_abort_中的任何更改都不会应用,直到线程的事件循环返回以处理其他函数为止。使用 WorkerThread时,很难验证它是否有效,有时它可以正常工作,而有时它会生成 分配错误错误,这似乎不起作用(尽管可能是由于完全不同的原因,但我并非如此)当然)。我想问一下您的意见,这是过早停止长时间运行的计算的正确方法吗?有没有其他方法可以比当前方法更强大?

最佳答案

How to stop a long-running function in another thread prematurely?


您是对的,唯一明智的方法是定期运行长时间运行的线程检查,检查是否应尽早停止。
请注意,您要检查的标志必须是原子的,或受互斥锁保护,或者必须以某种方式进行同步。否则,工作线程检查变量并且永远不会看到值更改是完全合法的(不,您不能为此使用 volatile)。

... which makes me think that inside a single thread (main GUI thread or a worker thread) only one function can run at a time ...


是的,这就是线程!它是一个线性的执行线程。它不能一次完成两件事。一次执行两件事是拥有多个线程的全部原因。
该方法应该是让工作线程等待工作,而主线程仅向其发送异步消息(开始使用此数据生成镜像,或中断处理,然后再次使用此数据开始,等等)。
如果主线程调用了应该在工作线程中发生的函数,那么,您已经在主线程中故意开始执行它,并且主线程在返回之前不会做任何事情。就像其他功能一样。

顺便说一句,您的设计有一个问题:如果不断被新数据打断,则可能永远无法完成生成单个图像。
通常的解决方案是双缓冲:您可以让工作线程完成当前图像的生成,而主线程则为下一个图像积累数据。工作人员完成一幅图像后,可以将其传递回主线程进行显示。然后,工作程序可以开始处理下一个,因此它将占用主线程为此准备的“脏”更新缓冲区。随后的更新再次添加到下一个图像的(现在为空)缓冲区中。

关于c++ - 如何过早停止长时间运行的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64695714/

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