Reputation: 115
In my application I have a thread run an object's function. In the function some elements of the object are changed, however I am unable to see these changes in my main thread.
I feel like I may not be altering the correct object. Is this accurate?
Thread:
thread_.emplace_back(&Philosopher::Live, philosopher_[i]);
Return:
Philosopher::_state current_state_;
current_state_ = philosopher_[i].ReturnState();
Upvotes: 0
Views: 80
Reputation: 7111
You are likely facing one of two problems*, and without a Minimal, Complete, Verifiable Example I can't tell you for sure which it is.
Because there is no context and declaration of philosopher[i
] I can't know for sure, but you may be passing a copy. Consider:
struct Philosopher
{
void Live();
int ReturnState();
private:
int state;
};
std::vector<Philosopher> philosopher_;
philosopher_.emplace_back(...);
std::vector<std::thread> thread_;
thread_.emplace_back(&Philosopher::Live, philosopher_[i]); // A copy of Philosopher is passed
...
int state = philosopher_[i].ReturnState(); // philosopher[i] has not changed.
However, if the std::vector<Philosopher>
was a std::vector<Philosopher*>
then you would not be passing a copy (hence why it's hard to see without the declaration of philosopher_
. If you have declared philosopher_
as a std::vector<Philosopher>
, you can fix it with std::ref
or by passing a pointer:
std::vector<Philosopher> philosopher_;
...
thread_.emplace_back(&Philosopher::Live, std::ref(philosopher_[i])); // A reference is passed
Pointer:
std::vector<Philosopher> philosopher_;
...
thread_.emplace_back(&Philosopher::Live, &philosopher_[i]); // A pointer is passed
Credit to @deviantfan for pointing out this next point in the comments. Consider:
struct Philosopher
{
void Live();
int ReturnState();
private:
int state;
};
std::vector<Philosopher> philosopher_;
philosopher_.emplace_back(...);
std::vector<std::thread> thread_;
thread_.emplace_back(&Philosopher::Live, std::ref(philosopher_[i]));
// There is no guarantee that by the time the code reaches here, Philosopher::Live would've had a chance to run and finish.
int state = philospher_[i].ReturnState();
You may not have allowed Philosopher::Live
a chance to run and finish. You can deal with this in a multitude of ways, but I will only cover "waiting for the thread to finish".
std::vector<Philosopher> philosopher_;
...
thread_.emplace_back(&Philosopher::Live, std::ref(philosopher_[i]));
thread_[i].lock(); // Wait for the thread to finish
int state = philospher_[i].ReturnState();
This may or may not be desired depending on what you are trying to accomplish. If you want to learn about some other ways, consider reading about std::mutex
and std::conditional_variable
*I realise at the time of writing this that you have solved your problem; however, this is just an in-depth answer aimed at helping people with similar problems (plus you may learn something new!) It seems like you may wish to use a mutex to employ thread-safety.
Upvotes: 2