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

C语言通过结构体传参给线程,实现多线程更新counter的技术问询

问题分析

兄弟,你当前的代码存在一个核心问题:你把main里counter的值直接拷贝到了结构体成员中,线程函数里修改的只是这个副本,和main里的原始变量完全是两个独立的内存空间,所以修改根本同步不回去。

解决方案

要让线程能真正修改main里的counter,得让结构体持有counter的指针(指向原始变量的内存地址);另外,多个线程操作共享变量时必须加同步机制(比如互斥锁),否则会出现竞态条件,导致数据错乱。

1. 调整结构体定义

把结构体里的int counter;改成int *counter;,同时加入互斥锁指针用于线程同步:

struct Args{
    char *name;
    int *counter;
    pthread_mutex_t *mutex;
};

2. 线程函数的正确实现

操作共享变量前先加锁,修改完成后解锁,保证线程安全:

void *Producer(void* args){
    struct Args *data = (struct Args*) args;
    
    // 加锁,确保同一时间只有一个线程操作counter
    pthread_mutex_lock(data->mutex);
    // 通过指针修改main里的原始counter
    (*data->counter)++;
    printf("Thread %s: counter updated to %d\n", data->name, *data->counter);
    // 解锁,让其他线程可以访问
    pthread_mutex_unlock(data->mutex);
    
    pthread_exit(NULL);
}

3. 主函数的调用逻辑

传递counter的地址给结构体,同时初始化并传递互斥锁:

int main(){
    pthread_t thread_id1, thread_id2;
    int counter = 0;
    pthread_mutex_t mutex;
    
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);
    
    struct Args args1, args2;
    args1.name = "Thread 1";
    args1.counter = &counter; // 传递counter的内存地址
    args1.mutex = &mutex;
    
    args2.name = "Thread 2";
    args2.counter = &counter;
    args2.mutex = &mutex;
    
    // 创建两个线程测试共享变量修改
    pthread_create(&thread_id1, NULL, Producer, &args1);
    pthread_create(&thread_id2, NULL, Producer, &args2);
    
    // 等待所有线程执行完毕
    pthread_join(thread_id1, NULL);
    pthread_join(thread_id2, NULL);
    
    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);
    
    printf("Main: final counter value is %d\n", counter);
    return 0;
}

关键注意点

  • 指针传递共享变量:通过把counter的地址存入结构体,线程能直接操作原始变量的内存,修改才会同步到main中。
  • 必须加同步锁:如果多个线程同时读写共享变量,互斥锁能避免竞态条件(比如两个线程同时读取counter=0,各自加1后结果还是1而不是2)。
  • 保证变量生命周期:要确保线程运行期间,结构体、counter、互斥锁这些资源都处于有效状态,不要在线程未结束就释放它们的内存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:35:03