Итак, у меня есть что-то вроде этого (C ++ 11):
class Foo
{
private:
std::vector<int> vec;
int val;
std::thread Foo_thread;
public:
Foo();
void StartLoop();
void WaitTermination() { this->Foo_thread.join(); }
void AddToVec(int dummy) { vec.push_back(dummy); }
void setter(int val) { this->val = val; }
};
void Foo::StartLoop()
{
while (true)
{
// some code . . .
this->vec.push_back(something);
}
}
Foo::Foo()
{
this->Foo_thread = std::thread(&Foo:SartLoop, this);
}
int main()
{
Foo* f = new Foo{};
f->WaitTermination();
}
Если я правильно понимаю, указатель f и экземпляр Foo живут в главном потоке. В конструкторе this->Foo_thread = std::thread(&Foo:SartLoop, this);
адрес экземпляра Foo передается в std :: thread, поэтому этот поток может получить доступ к членам этого объекта, например, в Foo :: StartLoop (): this-> vec.push_back.
Однако у класса Foo есть общедоступная функция AddToVec (), поэтому в main () я мог бы написать:
int main()
{
Foo* f = new Foo{};
f->AddToVec(78); // at this point, we modify the private vec member, both from the main thread and in the std::thread, if I undersand well
f->setter(67); // same problem, however it's easier to declare val as std::atomic<int>, but the above one is really problematic
f->WaitTermination();
}
Мой вопрос: хорошо ли я понимаю? Как я могу исправить этот код? Я хотел бы сохранить механизм конструктор создает поток.
Спасибо