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

C++中类的thread_local静态成员变量线程内初始化报错问题

类中thread_local静态成员变量的线程内初始化问题

问题代码

#include <cstdlib>
#include <cstdio>
#include <pthread.h>
#include <atomic>
#include <iostream>

using namespace std;

class A {
public:
    thread_local static int i;
};

typedef struct Args {
    A *a;
    int i;
} Args;

void* print(void* ptr) {
    Args *args = (Args*) ptr;
    thread_local int A::i = args->i;
    // args->a->i = args->i;
    cout << "(In thread) A.i = " << args->a->i << endl;
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    A *a = new A();
    Args a1, a2;

    a1.a = a;
    a1.i = 10;
    pthread_create(&thread1, NULL, &print, &a1);

    a2.a = a;
    a2.i = 20;
    pthread_create(&thread2, NULL, &print, &a2);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    cout << "(In main) A.i = " << a->i << endl;
    return 0;
}

编译错误

multithreaded_example.cpp: In function ‘void* print(void*)’:
multithreaded_example.cpp:21:24: error: qualified-id in declaration before ‘=’ token
  thread_local int A::i = args->i;
                        ^

错误原因

  1. 类静态成员定义位置违规:类内的thread_local static int i;只是声明,必须在类外部完成定义,不能在函数内部重新声明并初始化。
  2. thread_local初始化方式错误:依赖线程参数的初始化不能用声明式赋值(这种初始化是在变量首次使用前自动完成的,无法获取线程传入的参数),只能在线程函数内直接对已定义的thread_local成员做赋值操作。

修正方案

步骤1:类外部定义thread_local静态成员

在类定义之后添加以下代码,完成静态成员的定义(C++标准强制要求类静态成员必须类外定义):

thread_local int A::i;

步骤2:修改线程函数的初始化逻辑

删除错误的thread_local int A::i = args->i;,直接改为赋值操作,每个线程会操作自己专属的A::i副本:

A::i = args->i;

修正后的完整代码

#include <cstdlib>
#include <cstdio>
#include <pthread.h>
#include <atomic>
#include <iostream>

using namespace std;

class A {
public:
    thread_local static int i;
};

// 类外部定义thread_local静态成员
thread_local int A::i;

typedef struct Args {
    A *a;
    int i;
} Args;

void* print(void* ptr) {
    Args *args = (Args*) ptr;
    // 为当前线程的A::i副本赋值
    A::i = args->i;
    cout << "(In thread) A.i = " << A::i << endl;
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    A *a = new A();
    Args a1, a2;

    a1.a = a;
    a1.i = 10;
    pthread_create(&thread1, NULL, &print, &a1);

    a2.a = a;
    a2.i = 20;
    pthread_create(&thread2, NULL, &print, &a2);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    cout << "(In main) A.i = " << A::i << endl;
    return 0;
}

运行结果

(In thread) A.i = 10
(In thread) A.i = 20
(In main) A.i = 0

每个线程拥有独立的A::i副本,main线程的副本未被赋值,因此显示默认初始化的0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:41:04