mato
mato

Reputation: 533

why thread has no effect on change made on class variable?

#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;
}

Why does the execution of thread which eventually adds +1 to value has no effect? The std::cout is just zero. I was expecting 1.

Upvotes: 2

Views: 1598

Answers (2)

ABu
ABu

Reputation: 12259

As @JesperJuhl says, you are passing a copy of a so the main's variables is never modified, but, besides, references cannot be passed to other threads. The thread's parameters are always passed by value, so, you need to pass a pointer or a reference_wrapper, which allows to pass a reference, but wrapped in a copyable object:

#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;
}

Upvotes: 2

Jesper Juhl
Jesper Juhl

Reputation: 31465

You are passing a by value, so the thread gets its own private copy that is distinct from the a in main - the thread then modifies the copy and when the thread dies that object dies with it and the change to it is nowhere to be found. The a in main is never modified, so it retains its original value. You want to pass a reference or pointer if you want to change the a in main from within the thread.

You probably also want to read up on synchronization and atomic if you are going to be accessing variables from multiple threads.

Upvotes: 7

Related Questions