C语言pthread多线程排序时如何让sort函数正确访问传入数组
问题原因
你的代码存在4个核心错误,直接导致线程无法正确访问传入数组、排序逻辑失效:
- 线程入口函数
sort没有正确接收传入的参数:你把数组指针通过pthread_create的第四个参数传入后,函数内需要先把void*类型的参数强转为int*类型才能访问对应数组,你现在代码里直接使用未定义的array变量,属于访问非法内存,自然拿不到目标数据。 - 排序循环长度错误:拆分后的子数组长度是
mid = arrLen/2 = 10,但你在sort函数里循环边界写的是arrLen-1,会直接越界访问子数组外的内存,触发段错误。 - 没有等待线程执行完成:
pthread_create是异步调用,创建完线程后主线程会直接往下执行,你没调用pthread_join阻塞等待两个排序线程跑完,就直接调用printResult打印,这时候排序操作大概率还没执行完,输出的是未排序的原始数据。 - 细节语法问题:标准C中
main函数返回值应为int类型;原代码缺失time.h头文件会导致时间相关函数编译警告;第二个线程创建时传入的数组参数没有做显式指针转换,存在类型不匹配问题;定义的arrayCreator函数没有被调用,存在冗余代码。
修正方案
首先修改线程排序函数,正确接收传入的数组参数,调整循环边界适配子数组长度;其次创建两个线程后分别调用pthread_join等待执行完毕,最后再打印结果、合并数组。
修正后的完整可运行代码如下:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <time.h> const int arrLen = 20; const int mid = arrLen/2; void swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } // 线程排序入口,参数为待排序的int数组指针 void *sort(void *arg){ int *array = (int*)arg; // 把传入的void*参数转为int类型数组指针 int min_pos; // 子数组长度为mid,循环边界用mid,避免越界 for(int a=0; a<mid-1; a++){ min_pos = a; for(int b=a+1; b<mid; b++){ if(array[b] < array[min_pos]){ min_pos = b; } } swap(&array[min_pos], &array[a]); } pthread_exit(NULL); } void printResult(int array[], int len){ for(int k=0; k<len; k++){ printf("Num%d: %d\n", k, array[k]); } } // 合并两个排好序的子数组到主数组 void mergeArray(int mainArr[], int first[], int second[]){ for(int i=0; i<mid; i++){ mainArr[i] = first[i]; mainArr[i+mid] = second[i]; } } int main(){ printf("Program Initialized...\n"); int mainArray [arrLen], firstHalf[mid], secondHalf[mid]; srand((unsigned) time(NULL)); // 填充主数组 for(int i=0; i<arrLen; i++){ mainArray[i] = rand()%100; } printf("Array created...\n"); printf("Original main array:\n"); printResult(mainArray, arrLen); // 拆分主数组为两个子数组 for(int p=0; p<arrLen; p++){ if(p<mid){ firstHalf[p]=mainArray[p]; } else{ secondHalf[p-mid]=mainArray[p]; } } pthread_t tid1; pthread_t tid2; // 创建两个排序线程,传入对应子数组 pthread_create(&tid1, NULL, sort, (void*)firstHalf); pthread_create(&tid2, NULL, sort, (void*)secondHalf); // 阻塞等待两个线程执行完成 pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf("\nSorted first half:\n"); printResult(firstHalf, mid); printf("\nSorted second half:\n"); printResult(secondHalf, mid); // 合并两个子数组到主数组 mergeArray(mainArray, firstHalf, secondHalf); printf("\nMerged final array:\n"); printResult(mainArray, arrLen); return 0; }
编译时需要链接pthread库,对应编译命令为gcc your_file.c -o sort_demo -lpthread。
内容的提问来源于stack exchange,提问作者thecodermotor
相关产品推荐
相关产品推荐

