You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何C++线程调用实例成员函数时成员变量未共享?

C++线程间未共享类成员变量的问题分析

问题代码

// t.cpp

#include <iostream>
#include <thread>
#include <chrono>

class test
{
private:

public:
    void fcn1();
    void fcn2();
    uint8_t i = 0;

};


void test::fcn1()
{
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(999));
        std::cout << "hihi " << (float)i++ << std::endl;
    }
}


void test::fcn2()
{
    std::cout << "yoyo " << (float)i++ << std::endl;
}

test t;

std::thread tt(&test::fcn1, t);

int main()
{
    while (true)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        t.fcn2();
    }   
    return 0;
}

编译运行命令

g++ ./t.cpp -o t -lpthread; ./t

实际输出

hihi 0
yoyo 0
hihi 1
yoyo 1
hihi 2
yoyo 2
hihi 3
...

预期输出

hihi 0
yoyo 1
hihi 2
yoyo 3
hihi 4
yoyo 5
...

问题原因

核心错误是创建线程std::thread tt(&test::fcn1, t);时,第二个参数t是值传递,这会导致线程内部创建一个test类的副本,而非使用全局变量t本身。因此:

  • 线程中的fcn1操作的是副本的成员变量i
  • 主线程中的fcn2操作的是全局变量t的成员变量i
    两者完全是独立的实例,自然不会共享i的值,出现同步递增的现象。

修复方案

要让线程使用原实例,需要传递引用或指针:

  1. 使用std::ref传递引用:
std::thread tt(&test::fcn1, std::ref(t));
  1. 传递指针:
std::thread tt(&test::fcn1, &t);

修改后,两个线程会操作同一个实例的i,就能得到预期的交替递增输出。另外注意,多线程操作共享变量时,需要考虑线程安全问题(比如加锁),避免竞态条件导致的未定义行为。

内容的提问来源于stack exchange,提问作者furynerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:05:15