多线程-为啥在引用上工作不会改变它,而在指针上工作正常[重复]
Posted
技术标签:
【中文标题】多线程-为啥在引用上工作不会改变它,而在指针上工作正常[重复]【英文标题】:Multithreading - why working on a reference doesn't change it, while on a pointer works properly [duplicate]多线程-为什么在引用上工作不会改变它,而在指针上工作正常[重复] 【发布时间】:2014-07-24 23:22:04 【问题描述】:谁能解释一下原因
void doSomething(vector<int>& vec)
for (int i = 0; i < 100; ++i)
vec.push_back(i);
int main(int argc, char** argv)
vector<int> v;
thread t1(doSomething, v);
thread t2(doSomething, v);
t2.join();
t1.join();
cout << v.size() << endl;
return 0;
打印 0,而带有指针的相同内容打印 200
void doSomething(vector<int>* vec)
for (int i = 0; i < 100; ++i)
vec->push_back(i);
int main(int argc, char** argv)
vector<int>* v = new vector<int>();
thread t1(doSomething, v);
thread t2(doSomething, v);
t2.join();
t1.join();
cout << v->size() << endl;
return 0;
在这里处理引用不应该等于(处理指针)吗?
编辑:故意不是线程安全的
您能否提供我为什么需要使用 std::ref 的参考?
【问题讨论】:
你很幸运能得到任何东西。您有两个线程,一个向量并且没有锁定。任何事情都有可能发生。 @ZanLynx 绝对是指针版本。使用参考版本,它实际上是相当安全的,如果不是 OP 所期望的,如链接副本中所述。 @aruisdante:是的。如果它像 mewa 预期的那样工作,它也会有同样的问题。 @ZanLynx 我是故意这样做的,我想看看并发修改发生时会发生什么 【参考方案1】:1)您的代码不是线程安全的(在向量上并发push_back
)
2) 参数默认按值传递给std::thread
。这种复制参数的语义对于线程来说是很自然的:任何参数都将被复制/移动到线程可访问的存储中。这样做,std:::thread
会尽力避免对共享对象的并发访问。
使用std::ref
通过引用您的线程可调用来传递参数:
thread t1(doSomething, std::ref(v));
thread t2(doSomething, std::ref(v));
^^^^^^^^
没有std::ref
,gcc 和clang 都不会编译这段代码。
为了将来参考,std::thread
构造函数在 C++ 标准的第 30.3.1.2 节中进行了描述。
【讨论】:
您能否发布参考并解释原因?另外,它是用 msvc 实现的 @mewa 在这个答案的链接中有解释。主狙击手之前的code highlighs
都是指向各自模板的链接。检查std::thread
的构造函数以供参考
是的。我还进行了编辑以解释更多。基本上,std::thread
在参数上使用复制语义以避免(默认情况下)处理共享对象。【参考方案2】:
std::thread 不幸的是按值获取参数。即使您将其设置为通过引用获取,它最终仍会复制它。您可以使用 std::ref 通过引用传递。
【讨论】:
以上是关于多线程-为啥在引用上工作不会改变它,而在指针上工作正常[重复]的主要内容,如果未能解决你的问题,请参考以下文章