请考虑以下代码片段。使用 GCC 4.6.1,x
变为 0
,y
变为 1
。
为什么使用和不使用单独的线程会得到不同的结果?我应该如何修改代码以使两个版本产生相同的结果(即整数值递增 1?)
谢谢。
struct functor{
void operator()(int & x){
++x;
}
};
void tfunc(functor & f, int & x){
f(x);
}
int main(){
functor f;
int x = 0, y = 0;
std::thread t = std::thread(tfunc, f, x);
t.join();
std::cout << "with thread " << x << std::endl;
f(y);
std::cout << "without thread " << y << std::endl;
}
最佳答案
很容易看出发生了什么。只需替换 int
使用不可复制的类型(具有私有(private)复制构造函数的类型),编译器将为您指出 libstdc++
的确切位置尝试复制参数而不是使用引用。在我的例子中,它是 <tuple>
中的第 138 行标准标题。
这是否是标准的正确实现,我目前无法判断。
UPDATE 该标准表示 std::thread::thread
的每个参数应该满足 MoveConstructible
要求,并且传递给线程函数的实际参数是从 std::thread::thread
移动构造的争论。这意味着
- 线程函数获取参数的拷贝,并且
- 原件很可能在处理过程中被销毁。
所以通过引用传递东西是行不通的。
关于线程拼图中的c++ 11仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9001391/