Reputation: 676
I have a small problem and wondering if someone can help. I tried to demonstrate my problem in the most simple way possible. I am trying to pass an object by reference to multiple threads. Every thread calls "doSomething" which is a member function that belongs to the object "Example". The "doSomething" function should increment the counter. My gcc version is 4.4.7
The questions:
why is the value of the variable "counter" is not incremented although I passed the object by reference to the thread function.
The code:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
return 0;
}
The output:
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
value from A: 1
Upvotes: 6
Views: 11698
Reputation: 21576
while (true) {
std::thread t1(thread_task, b);
t1.join();
}
Two things you need to know here:
std::ref
to pass a reference. Working Example below:
#include <iostream>
#include <thread>
class Exmaple {
private:
int counter;
public:
Exmaple() {
counter = 0;
}
void doSomthing(){
counter++;
}
void print() {
std::cout << "value from A: " << counter << std::endl;
}
};
// notice that the object is passed by reference
void thread_task(Exmaple& o) {
o.doSomthing();
o.print();
}
int main()
{
Exmaple b;
for(int i =0; i < 10; i++) {
std::thread t1(thread_task, std::ref(b));
t1.join();
}
return 0;
}
Output:
value from A: 1
value from A: 2
value from A: 3
value from A: 4
value from A: 5
value from A: 6
value from A: 7
value from A: 8
value from A: 9
value from A: 10
See it Live.
Though going further you should also consider data race
Upvotes: 8
Reputation: 35164
Note that in std::thread t1(thread_task, b)
you pass b
by value to the constructor of std::thread
(as you call the constructor here, and not thread_task
directly). A solution could be to either to wrap b
by an std::ref
-object, or change your code to pass a pointer:
void thread_task(Exmaple* o) {
o->doSomthing();
o->print();
}
int main()
{
Exmaple b;
while (true) {
std::thread t1(thread_task, &b);
t1.join();
}
return 0;
}
Upvotes: 1
Reputation: 2533
I'm not very familiar with multithreading, but you're passing b
by value to the thread, and not by reference. The value of b
is then passed by reference to thread_task
, so the value is always 1.
According to the documentation, you have to write your thread like so to pass objects by reference:
std::thread t1(thread_task, std::ref(b));
Upvotes: 4