C++多线程修改传入对象不生效,如何让线程内改动同步到外部对象?
问题根本原因
你创建std::thread时向线程入口传递ClassA实例的方式错误:std::thread的构造函数默认会对传入的参数做拷贝构造,所以你三个线程里操作的都不是原始的全局对象a,而是各自独立的拷贝副本,线程操作完副本就销毁了,原始对象a从头到尾没有被修改过,所以最终三个属性值都是0。
修复方案
- 第一步:传递实例时用
std::ref包裹,让线程持有原始对象的引用而非拷贝。修改线程创建的代码为:
ClassA a; std::thread pt(&ClassA::startCounterA, std::ref(a)); pt.join(); std::thread ct(&ClassA::startCounterB, std::ref(a)); ct.join(); std::thread mt(&ClassA::startCounterC, std::ref(a)); mt.join();
你当前示例是串行创建线程、执行完一个再启动下一个,没有并发冲突,修改完参数传递逻辑就能得到正确的计数结果。
- 第二步:如果实际业务是三个线程并行执行,还需要保证计数操作的线程安全,避免并发读写的竞态问题,可以把三个计数器改为
std::atomic<int>类型:
#include <atomic> class ClassA{ std::atomic<int> counter_a = 0; std::atomic<int> counter_b = 0; std::atomic<int> counter_c = 0; void startCounterA() { this->counter_a++; } void startCounterB() { this->counter_b++; } void startCounterC() { this->counter_c++; } };
内容的提问来源于stack exchange,提问作者KOKO
相关产品推荐
相关产品推荐

