This is the example:
#include<iostream>
#include<thread>
using namespace std;
void f1(double& ret) {
ret=5.;
}
void f2(double* ret) {
*ret=5.;
}
int main() {
double ret=0.;
thread t1(f1, ret);
t1.join();
cout << "ret=" << ret << endl;
thread t2(f2, &ret);
t2.join();
cout << "ret=" << ret << endl;
}
And the output is:
ret=0
ret=5
Compiled with gcc 4.5.2, with and without -O2
flag.
Is this expected behavior?
Is this program data race free?
Thank you
The constructor of std::thread
deduces argument types and stores copies of them by value. This is needed to ensure the lifetime of the argument object is at least the same as that of the thread.
C++ template function argument type deduction mechanism deduces type T
from an argument of type T&
. All arguments to std::thread
are copied and then passed to the thread function so that f1()
and f2()
always use that copy.
If you insist on using a reference, wrap the argument using boost::ref()
or std::ref()
:
thread t1(f1, boost::ref(ret));
Or, if you prefer simplicity, pass a pointer. This is what boost::ref()
or std::ref()
do for you behind the scene.