gpt4 book ai didi

c++ - 是否可以从外部修改 OpenMP 线程中的对象?

转载 作者:太空宇宙 更新时间:2023-11-04 12:33:00 27 4
gpt4 key购买 nike

我使用 OpenMP 来并行化调用,如下所示:

#pragma omp parallel for
for(std::size_t iter = 0; iter < visitors.size(); ++iter)
{
VisitorSPtr visitor_sp = visitors.at(iter);

dataSetPtr->accept(*(visitor_sp.get());
}
// End of
// #pragma omp parallel for

由于 #pragma omp parallel for 指令,每个访问者都在不同的线程中使用。美好的。

在循环中调用的 dataSetPtr->accept() 函数检查访问者是否已被用户取消,如下所示:

    if(visitor.shouldStop())
break;

如果该调用返回 true,则不会执行访问。当用户单击一个按钮并发出一个信号,该信号被中继到访问者时,该取消被捕获,该信号设置一个成员 bool 变量以声明已请求取消。但是信号没有到达访问者并且 if(visitor.shouldStop()) 没有用,也就是说,即使取消信号被正确发出,它也永远不会计算为真。

连接是这样执行的(this 是从中建立连接的 MassDataIntegrator 对象实例,它接收取消信号并应将其中继给访问者实例):

      connect(this,
&MassDataIntegrator::cancelOperationSignal,
visitor_sp.get(),
&Visitor::cancelOperation,
Qt::QueuedConnection);

我的问题:如何从另一个线程中运行的代码修改 #pragma omp parallel for 循环中的对象?我认为使用指针会很简单。显然,我在这里遗漏了一些概念。谁能帮我解决这个误解?感谢您的关注。

已解决

由于某种原因(我将调查),上面的连接调用不起作用。所以我尝试使用 lambda,从表面上看,它像这样直接访问 Visitor 实例(我注释掉了替换的代码以显示差异):

  connect(this,
&MassDataIntegrator::cancelOperationSignal,
[visitor_sp](){visitor_sp->cancelOperation();});
//visitor_sp.get(),
//&TicChromTreeNodeCombinerVisitor::cancelOperation,
//Qt::QueuedConnection);

我们可以认为这个问题已经解决了。我该怎么做?

最佳答案

如果您从 OpenMP 中的多个线程访问数据位置,并且至少有一个访问是写入访问,则必须使用 atomic 保护对该位置的所有读写访问 指令(或其他避免竞争条件并确保内存一致性的方法)。

简单来说,shouldStop 应该按照以下方式实现:

bool r;
#pragma omp atomic read
r = this->cancelFlag_;
return r;

cancelOperation像:

#pragma omp atomic write
this->cancelFlag_ = true;

这既确保在写入 bool 需要两次操作的不太可能的情况下没有竞争条件,也意味着适当的内存刷新以确保写入的结果在其他线程中可见.

关于c++ - 是否可以从外部修改 OpenMP 线程中的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57890725/

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