We know how to construct a thread without any input
arguments. But a function printNTimes(int n, const std::string&
msg) requires two arguments. How to run it in a separate
thread is described below.
The code runs printNTimes with arguments 5
and msg in a new thread. But something unexpected happens if
you don’t have a const reference. Let us consider a
referenceArguments.cpp below
This looks perfectly reasonable, at least to me. But it doesn’t compile.
The error message is quite cryptic. The solution is to add
std::ref around str:
Explanation
The reasoning behind it is that a thread, during a construction, takes a
function and copies all of the arguments to its internal storage. Then,
accordingly to the function signature, thread passes the copies to the function
by values or references. If the function expects a reference, it
gets a reference to an internal copy of the object.
In the example
the thread t copies arguments 5 and
msg to its internal storage. Then, the function
printNTimes recieves a reference to the internal copy of the
msg not a reference to the original msg.
If we use std::ref, the function correctly gets a reference
to the original object, like in the example
In the case of non const reference, we get a compiler error if we don’t use the
std::ref, but in the case of const reference we don’t get an
error . Therefore, I recommend using std::ref every time when
we have references.
Another example
Here is arguments.cpp, which uses the
printNTimes function from above.
The output might be:
It looks a bit strange. This is because of so called data races.
Summary
We learned how to pass an argument to a function, which will run in a separate
thread. The std::ref is used for passing a reference to a
variable.
In the next article, we will investigate why is the output of the final
program strange – in concurrent language: we will explore data races.