在我的应用程序中,我有一个线程运行对象的功能。在函数中,对象的某些元素被更改,但是我无法在主线程中看到这些更改。
我觉得我可能没有改变正确的对象。这准确吗?
发
thread_.emplace_back(&Philosopher::Live, philosopher_[i]);
返回:
Philosopher::_state current_state_;
current_state_ = philosopher_[i].ReturnState();
答案 0 :(得分:2)
你可能面临两个问题之一*,如果没有Minimal, Complete, Verifiable Example,我无法确定它是什么。
由于没有philosopher[i
]的上下文和声明,我无法确定,但您可能会传递副本。考虑:
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.
但是,如果std::vector<Philosopher>
是std::vector<Philosopher*>
,那么您就不会传递副本(因此,如果没有声明philosopher_
,很难看到它。如果您已将philosopher_
声明为std::vector<Philosopher>
,则可以使用std::ref
或通过传递指针来修复它:
std::vector<Philosopher> philosopher_;
...
thread_.emplace_back(&Philosopher::Live, std::ref(philosopher_[i])); // A reference is passed
指针:
std::vector<Philosopher> philosopher_;
...
thread_.emplace_back(&Philosopher::Live, &philosopher_[i]); // A pointer is passed
感谢@deviantfan指出评论中的下一个要点。考虑:
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();
您可能没有让Philosopher::Live
有机会跑步和完成。你可以通过多种方式处理这个问题,但我只会覆盖&#34;等待线程完成&#34;。
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();
取决于您要完成的任务,这可能是也可能不是。如果您想了解其他一些方法,请考虑阅读std::mutex
和std::conditional_variable
*我在写这篇文章时意识到你已经解决了你的问题;然而,这只是一个深入的答案,旨在帮助有类似问题的人(加上你可能会学到新的东西!)似乎你可能希望使用a mutex来使用线程安全。