为什么线程对类变量所做的更改没有影响?

why thread has no effect on change made on class variable?

本文关键字:有影响 线程 类变量 为什么      更新时间:2023-10-16
#include <iostream>
#include <thread>
using namespace std;
struct A{
void Add(){
++val;
} 
int val = 0;
};
int main(){
A a;
thread t(&A::Add,a);
t.join();
std::cout << a.val << std::endl;
}

为什么最终将 +1 添加到值的线程的执行没有效果?std::cout 只是零。我期待 1。

您正在按值传递a,因此线程获得自己的私有副本,该副本不同于main中的a- 然后线程修改副本,当线程死亡时,该对象随之死亡,并且找不到对它的更改。main中的a永远不会修改,因此它保留其原始值。如果要从线程中更改main中的a,则需要传递引用或指针。

如果要从多个线程访问变量,您可能还想阅读同步原子

正如@JesperJuhl所说,您正在传递a的副本,因此 main 的变量永远不会被修改,但除此之外,引用不能传递给其他线程。线程的参数总是按值传递的,因此,您需要传递指针或reference_wrapper,这允许传递引用,但包装在可复制的对象中:

#include <iostream>
#include <thread>
using namespace std;
struct A{
void Add(){
++val;
} 
int val = 0;
};
int main(){
A a;
// Passing a reference_wrapper is the standard way.
// Passing a pointer would imply to change your method signature
// and implementation if it were a free function instead of a 
// class member function.
// In your specific case it is irrelevant though.
thread t(&A::Add,std::ref(a));
// or thread t(&A::Add,&a);
t.join();
std::cout << a.val << std::endl;
}