Безопасен ли запуск std :: thread в потоке конструктора класса? - PullRequest
0 голосов
/ 01 декабря 2019

Итак, у меня есть что-то вроде этого (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();
}

Мой вопрос: хорошо ли я понимаю? Как я могу исправить этот код? Я хотел бы сохранить механизм конструктор создает поток.

Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...