将参数传递给std :: thread,C++的区别

Edu*_*yan 7 c++ multithreading c++11

来自Nikolai Josuttis的Quiote - 标准库C++ 11:

如果使用非本地资源,分离的线程很容易成为问题.问题是你失去了对分离线程的控制,并且没有简单的方法来确定它是否运行以及运行多长时间.因此,请确保分离的线程在其生命周期结束后不访问任何对象.因此,通过引用将变量和对象传递给线程始终是一种风险.强烈建议按值传递参数.

作者进一步解释说,即使您将引用作为函数参数传递给线程,它仍然按值传递,因此您必须指定引用std::ref.

我有这些问题,请参阅以下代码:

void f(std::vector<int> V){...}
void g(std::vector<int>& V){...}

std::vector<int> V;

std::thread t1(f, V);
std::thread t2(f, std::ref(V));
std::thread t3(g, V);
std::thread t4(g, std::ref(V));
Run Code Online (Sandbox Code Playgroud)

这四行有什么不同?哪条线是等价的?
我没有加入或分离线程,它不是关于那个,它是关于传递函数参数的方式.

Fra*_*ank 6

t1:

这只是传递V给线程的副本.

t2:

与此类似t1,将副本V传递给线程,但实际副本是在被调用的线程而不是调用者线程中进行的.这是一个重要的区别,因为V在线程开始时应该更改或停止存在,您将最终得到不同的向量或未定义的行为.

t3:

这应该无法编译,因为线程会将向量移动到LValue引用中,这应该是非法的.

t4:

这通过引用传递向量.对传递的引用的任何修改都将适用于V.