почему поток не влияет на изменения, внесенные в переменную класса? - PullRequest
0 голосов
/ 27 июня 2018
#include <iostream>
#include <thread>

using namespace std;

struct A{

 void Add(){
    ++val;
 } 

 int val = 0;
};

int main(){
   A a;
   thread t(&A::Add,a);
   t.join();

   std::cout << a.val << std::endl;
}

Почему выполнение потока, который в конечном итоге добавляет +1 к значению, не имеет никакого эффекта? Std :: cout это просто ноль. Я ожидал 1.

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Как говорит @JesperJuhl, вы передаете копию a, поэтому переменные main никогда не изменяются, но, кроме того, ссылки не могут быть переданы другим потокам. Параметры потока всегда передаются по значению, поэтому вам нужно передать указатель или reference_wrapper, который позволяет передавать ссылку, но заключенный в копируемый объект:

#include <iostream>
#include <thread>

using namespace std;

struct A{

 void Add(){
    ++val;
 } 

 int val = 0;
};

int main(){
   A a;

   // Passing a reference_wrapper is the standard way.

   // Passing a pointer would imply to change your method signature
   // and implementation if it were a free function instead of a 
   // class member function.
   // In your specific case it is irrelevant though.
   thread t(&A::Add,std::ref(a));
   // or thread t(&A::Add,&a);

   t.join();

   std::cout << a.val << std::endl;
}
0 голосов
/ 27 июня 2018

Вы передаете a по значению, поэтому поток получает свою собственную личную копию, отличную от a в main - поток затем изменяет копию, и когда поток умирает, этот объект умирает вместе с ним и изменения к нему нигде не найти. a в main никогда не изменяется, поэтому он сохраняет свое первоначальное значение. Вы хотите передать ссылку или указатель, если хотите изменить a in main из потока.

Возможно, вы также захотите прочитать о синхронизация и атомарный , если вы собираетесь обращаться к переменным из нескольких потоков.

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