如何正确更改函数内的对象?

时间:2015-07-20 03:31:49

标签: c++ multithreading

在我的应用程序中,我有一个线程运行对象的功能。在函数中,对象的某些元素被更改,但是我无法在主线程中看到这些更改。

我觉得我可能没有改变正确的对象。这准确吗?

thread_.emplace_back(&Philosopher::Live, philosopher_[i]);

返回:

Philosopher::_state current_state_;
current_state_ = philosopher_[i].ReturnState();

1 个答案:

答案 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::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::mutexstd::conditional_variable

*我在写这篇文章时意识到已经解决了你的问题;然而,这只是一个深入的答案,旨在帮助有类似问题的人(加上你可能会学到新的东西!)似乎你可能希望使用a mutex来使用线程安全。