我正在编写一个程序(理想情况下)需要两个线程同时运行。
我有一个全局矢量变量myObjects来跟踪我的对象:
vector<Object> myObjects;
类型为MoND
的对象将会进行繁重的工作。
它以向量作为参数进行初始化,并推动&#34;对象&#34;进入矢量。到目前为止没问题。
MoND mySim = MoND(myObjects);
在main中,需要使用myObjects
作为参数调用mySim的方法。
在我用于测试的非线程版本中,这有效(在100次迭代后运行失败):
int main(int argc, char** argv) {
...
mySim.Run(myObjects);// Run simulation on Objects
glutMainLoop(); // Enter the event-processing loop
return 0;
}
通过工作,我的意思是更改Object
中存储的myObjects
的属性。
这需要持续和同时运行,因此它并不理想。
使用线程:
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()
接收myObject并更改其值,但这些不会转换为主线程使用的myObjects
。是否为新线程在内存中创建了myObjects
的另一个实例?
(是的,我确实通过引用传递,非线程版本确实更新了值)
所以我知道逻辑工作(一切都按预期工作,没有线程)。 我曾尝试使用原子,但说实话,我无法使用原子或其内容。
如何强制两个线程在内存中的myObjects
实例上工作(即让它们共享变量)?
有些观点:
不,我不担心线程安全,因为只有一个线程写入,另一个只是读取(读/写顺序不重要)
Run()
通过方法SetPos(args..)
和SetVel(args..)
答案 0 :(得分:11)
std::thread
构造函数复制其参数,以确保它们在被操作时仍处于活动状态。
为避免这种情况,您可以使用std::ref
:
thread t1(&MoND::Run, mySim, std::ref(myObjects));
在这里,您承诺照顾对象的生命。
std::bind
和std::async
出于同样的原因表现出相同的行为。
请注意,mySim
也正在复制,但是如果不想复制,也可以传递指针。
答案 1 :(得分:0)
由于您希望跨线程共享的变量是全局变量,因此解决方案更简单:不要将其作为参数传递。
整个计划都可以看到全局变量。