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
相关产品推荐
相关产品推荐

