gpt4 book ai didi

c++ - 尽管调用了 wakeAll,仍有 2 个线程在 QWaitCondition 上等待

转载 作者:行者123 更新时间:2023-11-28 03:20:47 26 4
gpt4 key购买 nike

我已经对一些几何图形进行了线程迭代生成。我使用 VTK 进行渲染。每次迭代后,我想显示(渲染)当前进度。我的方法按预期工作,直到最后 2 个线程挂起等待 QWaitCondition。它们被阻止,即使它们在 QWaitCondition 队列中的状态是 wakenUp(通过调试器检查)。我怀疑 2 个线程的数量与我的处理器的 4 个内核有某种联系。

简化代码如下。我做错了什么以及如何解决?

class Logic
{
QMutex threadLock, renderLock;
//SOLUTION: renderLock should be per thread, not global like this!
QWaitCondition wc;
bool render;
...
}

Logic::Logic()
{
...
renderLock.lock(); //needs to be locked for QWaitCondition
}

void Logic::timerProc()
{
static int count=0;
if (render||count>10) //render wanted or not rendered in a while
{
threadLock.lock();
vtkRenderWindow->Render();
render=false;
count=0;
wc.wakeAll();
threadLock.unlock();
}
else
count++;
}

double Logic::makeMesh(int meshIndex)
{
while (notFinished)
{
...(calculate g)
threadLock.lock(); //lock scene
mesh[meshIndex]->setGeometry(g);
render=true;
threadLock.unlock();
wc.wait(&renderLock); //wait until rendered
}
return g.size;
}

void Logic::makeAllMeshes()
{
vector<QFuture<double>> r;
for (int i=0; i<meshes.size(); i++)
{
QFuture<double> future = QtConcurrent::run<double>(this, &Logic::makeMesh, i);
r.push_back(future);
}

while(any r is not finished)
QApplication::processEvents(); //give timer a chance
}

最佳答案

您的代码中至少有一个缺陷。 countrender 属于临界区,这意味着它们需要防止并发访问。

假设有更多线程在等待 wc.wait(&renderLock);。有人在某处执行 wc.wakeAll();。所有线程都被唤醒。假设至少有一个线程认为 notFinished 为真(如果您的任何代码有意义,这必须 是可能的)并返回执行:

    threadLock.lock(); //lock scene
mesh[meshIndex]->setGeometry(g);
render=true;
threadLock.unlock();
wc.wait(&renderLock) <----OOPS...

线程第二次回来,他没有锁renderLock。所以 Kamil Klimek 是对的:你在一个你不持有的互斥锁上调用 wait

你应该在构造函数中移除锁,并在调用条件之前锁定。无论您在哪里锁定 renderlock,线程都不应该持有 threadlock

关于c++ - 尽管调用了 wakeAll,仍有 2 个线程在 QWaitCondition 上等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15496857/

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