C语言使用mutex同步线程时线程打印的int值乱序重复问题求助
问题根因
- 所有线程共享了同一个
struct thread_data结构体实例:你在循环中反复修改同一个thread_array->offset的值,而线程创建后不会立刻执行入口函数,等到子线程读取offset时,主线程可能已经将该值覆盖为后续循环的i值,最终出现重复、异常的数值 - 互斥锁使用逻辑错误:你仅在子线程打印时加锁,完全没有覆盖「主线程写offset」和「子线程读offset」的竞争区间,加锁无法解决参数传递的竞争问题
- 代码存在其他基础错误:
scanf("%d",workers)缺少取地址符&,会导致非法内存访问;malloc申请了1亿字节的无用空间,且没有按结构体数组下标分配独立的参数实例,未定义线程ID数组thread就直接使用
修复方案
- 为每个线程分配独立的
struct thread_data实例,避免多个线程共享同一块参数内存 - 修正
scanf传参、内存分配、变量未定义等基础错误 - 如果需要严格按1、2、3...的顺序打印输出,仅靠互斥锁无法实现(操作系统的线程调度顺序是随机的),需要额外加条件变量等顺序同步逻辑,或者在子线程执行完成后由主线程统一按顺序输出结果
修正后的核心代码示例
主文件代码
#include "common.h" // 内含pthread_mutex_t lock; #include "threadwork.c" void *thread_work(void *arg); int main(void) { int workers; pthread_t *thread; struct thread_data *thread_array; // 修正scanf传参错误,加取地址符& scanf("%d", &workers); // 按需分配线程ID数组和参数数组的空间 thread = malloc(sizeof(pthread_t) * workers); thread_array = malloc(sizeof(struct thread_data) * workers); if(pthread_mutex_init(&lock, NULL)!=0) { printf("\n mutex init failed\n"); return 1; } for(int i = 0; i < workers; i++){ // 给第i个线程的独立参数结构体赋值 thread_array[i].offset = i; // 传入第i个独立参数结构体的地址 int thread_id = pthread_create(&thread[i], NULL, thread_work, &thread_array[i]); if(thread_id == -1){ perror("fehler bei thread_id"); } } for(int i = 0; i < workers; i++){ pthread_join(thread[i], NULL); } // 释放资源 free(thread); free(thread_array); pthread_mutex_destroy(&lock); return 0; }
threadwork文件代码
void *thread_work(void *arg){ struct thread_data *rec_data = (struct thread_data *) arg; pthread_mutex_lock(&lock); // 此处打印的数值不会再重复,但输出顺序仍可能随线程调度随机 printf("%d\n", rec_data->offset); pthread_mutex_unlock(&lock); return (void*)NULL; };
内容的提问来源于stack exchange,提问作者need_help_1234
相关产品推荐
相关产品推荐

