C++11 线程不修改相同的值

c++11 threads don't modify same values

本文关键字:修改 线程 C++11      更新时间:2023-10-16

我正在编写一个程序,(理想情况下)需要两个线程同时运行。

我有一个全局向量变量myObjects来跟踪我的对象:

vector<Object> myObjects;

和一个类型为MoND的对象,它将完成繁重的工作。它以vector作为参数初始化,并将"Objects"压入vector中。到目前为止还没有问题。

MoND  mySim =  MoND(myObjects);

在main中,mySim的方法需要以myObjects作为参数来调用。在我用于测试的非线程版本中,这是有效的(运行100次迭代后跳出):

int main(int argc, char** argv) {
  ...
  mySim.Run(myObjects);// Run simulation on Objects
  glutMainLoop();      // Enter the event-processing loop                                                                                            
  return 0;
}

这里的功是指改变了储存在myObjects中的Object的性质。这需要持久且并发地运行,所以它不是理想的。

使用线程:

int main(int argc, char** argv) {
  ...
  thread t1(&MoND::Run, mySim, myObjects);// Run simulation on Objects
  glutMainLoop();      // Enter the event-processing loop                                                                                            
  return 0;
}

这没有达到预期的效果。Run()接收myObjects并更改它们的值,但是这些值不会被转换到主线程正在使用的myObjects。是否在内存中为新线程创建了另一个myObjects实例?(是的,我确实通过引用传递,非线程版本确实更新了值)

所以我知道逻辑工作(一切工作如预期没有线程)。我试过使用atomic,但说实话,我不能让它与vector或其内容一起工作。

我怎样才能强迫两个线程在内存中的myObjects的同一个实例上工作(即让它们共享变量)?

一些要点:

  • 不,我不担心线程安全,因为只有一个线程写,另一个只是读(读/写的顺序不重要)

  • Run()通过SetPos(args..)SetVel(args..)方法更新Object类对象中私有变量的值

std::thread构造函数复制它的参数,以确保它们在被操作时仍然是活的。

为了避免这种情况,您可以使用std::ref:
thread t1(&MoND::Run, mySim, std::ref(myObjects));

在这里你要保证你的对象的生命周期。

std::bindstd::async由于相同的原因表现出相同的行为。

注意mySim也被复制了,但是如果你不想复制,你也可以传递一个指针。

由于您希望跨线程共享的变量是全局变量,因此解决方案甚至更简单:根本不将其作为参数传递。

全局变量在整个程序中是可见的。