#include <thread>
#include <string>
#include <vector>
#include <chrono>
using namespace std;
void f(const vector<string>& coll)
{
this_thread::sleep_for(1h);
//
// Is coll guaranteed to be valid before exiting this function?
//
}
int main()
{
{
vector<string> coll(1024 * 1024 * 100);
thread(f, coll).detach();
}
//
// I know std::thread will copy arguments into itself by default,
// but I don't know whether these copied objects are still valid
// after the std::thread object has been destroyed.
//
while (true);
}
Is it safe to pass arguments by reference into a std::thread function?
If you need to pass the argument to a thread by reference, it must be wrapped in a reference wrapper. This is quite straightforward with the helper function std::ref .
In c++11 to pass a referenceto a thread, we have std::ref(). std::thread t3(fun3, std::ref(x)); In this statement we are passing reference of x to thread t3 because fun3() takes int reference as a parameter.
For cases where multiple arguments must be passed, this limitation is easily overcome by creating a structure which contains all of the arguments, and then passing a pointer to that structure in the pthread_create() routine. All arguments must be passed by reference and cast to (void *).
std::thread::operator= thread objects cannot be copied (2).
The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g., with std::ref or std::cref). So, you might use std::reference_wrapper through std::ref / std::cref: auto thread1 = std::thread (SimpleThread, std::ref (a));
(or std::cref instead of std::ref, as appropriate). Per notes from cppreference on std:thread: The arguments to the thread function are moved or copied by value. If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref ).
If a reference argument needs to be passed to the thread function, it has to be wrapped (e.g. with std::ref or std::cref ). The capture, sensibly, defaults to capture by value because otherwise things would fail horribly if the parameter went away before the thread could read it.
When passing an argument to a procedure, be aware of several different distinctions that interact with each other: Whether the underlying programming element is modifiable or nonmodifiable Whether the argument data type is a value type or a reference type
As @T.C.'s comment, you're not passing reference to thread, you just make a copy of the vector in the thread:
thread(f, coll).detach(); // It's NOT pass by reference, but makes a copy.
If you really want to pass by reference, you should write this:
thread(f, std::ref(coll)).detach(); // Use std::ref to pass by reference
Then the code will get segment fault if the thread tries to access the vector, since when the thread runs, it's very likely the vector is already destructed (because it went out of it's scope in the main program).
So to your question:
Is it safe to pass arguments by reference into a
std::thread
function?
Is coll
guaranteed to be valid before exiting this function?
coll
to the constructor of a std::thread
in main
function, because coll
is an object, it is decay
copied. This decay
copy essentially move
s the vector (so it becomes rvalue), which will bind to the coll
parameter in f
during the execution of the thread. (Thanks for the comment by @Praetorian)Is it safe to pass arguments by reference into a std::thread
function?
decay
copied, so you actually never pass anything by reference to std::thread
.Reference for std::decay
: http://www.cplusplus.com/reference/type_traits/decay/
std::thread
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With