多线程桶排序中pthread_create传参异常:前几段子序列值丢失排查
问题根源与修复方案
核心问题
你所有线程都在共享同一个thread_argv1结构体实例。主线程循环会快速修改这个结构体的startAddr和tid值,而子线程启动是异步的——前几个线程还没来得及读取参数,主线程已经把结构体内容更新成了后续线程的参数,导致前几段子序列的参数被覆盖,输出自然不符合预期。
修复方法
给每个线程分配独立的参数结构体,确保每个线程拿到的参数不会被主线程或其他线程修改。以下是两种常用实现方式:
方式1:动态分配结构体实例
在循环中为每个线程单独malloc一个thread_argv结构体,填充参数后传给线程,线程执行完毕后释放内存:
#include <stdlib.h> struct thread_argv { unsigned int * startAddr; long fragSize; pthread_t tid; // 改为直接存储tid,无需指针 }; // 主线程循环部分 unsigned int * ptr = intarr; pthread_t tids[numThread]; long fragSize = ...; for (int i=0; i<numThread; i++){ struct thread_argv *argv = malloc(sizeof(struct thread_argv)); argv->startAddr = ptr; argv->fragSize = fragSize; argv->tid = tids[i]; // pthread_create第一个参数需要传入线程ID的地址 pthread_create(&tids[i], NULL, threadFunc, (void *) argv); ptr += fragSize; } // 线程函数 void * threadFunc(void * arg){ struct thread_argv * argv = (struct thread_argv *) arg; for(int i=0; i<argv->fragSize; i++){ // 用%p打印地址更标准,tid转long避免类型不匹配 printf("Tid: %ld, Address: %p, Value: %u\n", (long)argv->tid, argv->startAddr, *argv->startAddr); argv->startAddr++; } free(argv); // 释放动态分配的内存 return NULL; }
方式2:使用结构体数组
预先定义一个thread_argv数组,每个元素对应一个线程的参数,避免动态内存分配:
struct thread_argv { unsigned int * startAddr; long fragSize; pthread_t tid; }; // 主线程部分 unsigned int * ptr = intarr; pthread_t tids[numThread]; struct thread_argv thread_args[numThread]; long fragSize = ...; for (int i=0; i<numThread; i++){ thread_args[i].startAddr = ptr; thread_args[i].fragSize = fragSize; thread_args[i].tid = tids[i]; pthread_create(&tids[i], NULL, threadFunc, (void *)&thread_args[i]); ptr += fragSize; } // 线程函数 void * threadFunc(void * arg){ struct thread_argv * argv = (struct thread_argv *) arg; for(int i=0; i<argv->fragSize; i++){ printf("Tid: %ld, Address: %p, Value: %u\n", (long)argv->tid, argv->startAddr, *argv->startAddr); argv->startAddr++; } return NULL; }
额外注意点
pthread_create的第一个参数必须是pthread_t*类型(即线程ID变量的地址),原代码直接传tids[i]是错误的,需改为&tids[i]。- 打印内存地址时,用
%p格式符比%ld更标准,能适配不同平台的指针长度。 - 线程ID
pthread_t可能不是long类型,打印时强制转换为long是通用的兼容做法。
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

