I'm writing a program that (ideally) requires two threads to run simultaneously.
I have a global vector variable myObjects to keep track of my Objects:
vector<Object> myObjects;
And a object of type MoND
that will be doing the heavy lifting.
It is initialized with the vector as an argument and it pushes "Objects" into the vector. No problem so far.
MoND mySim = MoND(myObjects);
In main, a method of mySim needs to be called with myObjects
as an argument.
In a non-threaded version I used for testing, this works (run bails out after 100 iterations):
int main(int argc, char** argv) {
...
mySim.Run(myObjects);// Run simulation on Objects
glutMainLoop(); // Enter the event-processing loop
return 0;
}
By works I mean changes the properties of the Object
s stored in myObjects
.
This needs to run persistently and concurrently so it's not ideal.
Using threading:
int main(int argc, char** argv) {
...
thread t1(&MoND::Run, mySim, myObjects);// Run simulation on Objects
glutMainLoop(); // Enter the event-processing loop
return 0;
}
This doesn't have the desired effect.
Run()
receives myObjects and changes their values, but these are not translated to the myObjects
being used by the main thread. Is another instance of myObjects
created in memory for the new thread?
(yes, I did pass by reference and the non-threaded version does update the values just fine)
So I know the logic works (everything works as expected without threading). I have tried to use atomic but to be honest I can't get it to work with a vector or its contents.
How can I force the two threads to work on the same instance of myObjects
in memory (i.e. get them to share the variable)?
Some points:
No, I'm not worried about thread safety as only one thread writes, the other just reads (order of reading/writing is unimportant)
Run()
updates the values of private variables in objects of class Object through methods SetPos(args..)
and SetVel(args..)
The std::thread
constructor copies its arguments to make sure that they are still alive when they are being operated on.
To avoid that, you can use std::ref
:
thread t1(&MoND::Run, mySim, std::ref(myObjects));
Here you promise that you take care of your object's lifetime.
std::bind
and std::async
exhibit the same behavior out of the same reasons.
Note that mySim
is also being copied, here however you could also pass a pointer if don't want the copy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With