Debian Linux下多线程排序程序出现undefined reference错误求助
问题分析与解决方案
嘿,我帮你仔细梳理了代码里的问题,先从导致你遇到「undefined reference to function」错误的直接原因说起,再一步步修正其他逻辑问题,让你的多线程排序程序正常工作。
1. 触发链接错误的核心原因
你遇到的undefined reference错误主要来自两个地方:
- pthread库未链接:使用POSIX线程库时,编译必须加上
-lpthread参数,否则链接器找不到pthread_create这类线程相关函数;而且你还把pthread_create拼写成了threadcreate,这也会导致链接器找不到对应函数。 - 函数名大小写不匹配:你声明的快速排序函数是
quickSort(大写S),但调用时写成了quicksort(小写s),链接器自然找不到对应的实现。
2. 代码中的其他关键错误与修复
除了链接问题,你的代码还有不少逻辑错误,咱们一个个修正:
(1)随机数去重逻辑完全失效
你当前的去重循环for(j=0; j<1; j++)只检查了第0个元素,根本没做到真正的去重。应该改成遍历所有已经生成的元素:
for(i=0; i<800; i++){ sayilar[i] = 1 + (rand() % 800); // 遍历之前所有元素检查重复 for(j=0; j<i; j++){ if(sayilar[j] == sayilar[i]){ i--; // 重新生成当前元素 break; } } }
(2)函数嵌套定义不符合C语法
你把Sirala函数的定义放在了main函数内部,C语言不允许在函数里定义另一个函数,得把它移到main外面,和quickSort、partition这些函数放在一起。
(3)partition函数未完成
你的partition函数只定义了变量,完全没有实现快速排序需要的分区逻辑,补全后的实现如下:
int partition(int a[], int sol, int sag){ int pivot, i, j, t; pivot = a[sol]; i = sol; j = sag + 1; do { do i++; while(a[i] < pivot && i <= sag); do j--; while(a[j] > pivot); if(i < j){ t = a[i]; a[i] = a[j]; a[j] = t; } } while(i < j); t = a[sol]; a[sol] = a[j]; a[j] = t; return j; }
(4)第三个线程缺失合并逻辑
你当前的第三个线程只是调用了快速排序,完全没实现需求里的「合并两个有序序列」功能。需要先写一个合并有序数组的函数,再在第三个线程里调用它:
// 合并两个有序子数组的函数 void merge(int arr[], int left, int mid, int right) { int i, j, k; int n1 = mid - left + 1; int n2 = right - mid; // 创建临时数组存储两个子序列 int L[n1], R[n2]; // 复制数据到临时数组 for (i = 0; i < n1; i++) L[i] = arr[left + i]; for (j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; // 合并临时数组回原数组 i = 0; j = 0; k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } // 复制剩余元素 while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } }
然后在第三个线程的分支里替换原来的排序逻辑:
else { // 合并前300个(0-299)和后500个(300-799)有序序列 merge(sayilar, 0, 299, 799); printf("合并后的完整有序数组:\n\n"); for(i = 0; i < 800; i++){ printf("%d - ", sayilar[i]); } }
(5)线程串行执行,未发挥并行优势
你当前的代码创建一个线程就立即pthread_join等待它结束,这样三个线程是串行运行的,完全没用到多线程的并行能力。应该先创建所有线程,再统一等待它们完成:
// 先批量创建所有线程 for(t=0; t<NUM_THREADS; t++){ rc = pthread_create(&threads[t], NULL, Sirala, (void *)t); if(rc){ printf("Hata, thread oluşturulamadı. Thread: %d\n", rc); exit(-1); } } // 再等待所有线程执行完毕 for(t=0; t<NUM_THREADS; t++){ pthread_join(threads[t], NULL); printf("\n\n"); }
3. 正确的编译命令
在Debian下编译时,一定要加上-lpthread参数链接pthread库,命令如下:
gcc sort_thread.c -o sort_thread -lpthread
修正后的完整代码
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #define NUM_THREADS 3 int sayilar[800]; int kontrol=0; void *Sirala(void *param); void quickSort(int[], int, int); int partition(int[], int, int); void merge(int arr[], int left, int mid, int right); int main(int argc, char *argv[]){ int i,j; srand(time(NULL)); // 生成800个唯一随机数 for(i=0; i<800; i++){ sayilar[i] = 1+ (rand() % 800); // 检查重复元素 for(j=0; j<i; j++){ if(sayilar[j]== sayilar[i]){ i--; break; } } } pthread_t threads[NUM_THREADS]; int rc; long t; // 创建所有线程 for(t=0; t<NUM_THREADS; t++){ rc = pthread_create(&threads[t], NULL, Sirala, (void *)t); if(rc){ printf("Hata, thread oluşturulamadı. Thread: %d\n", rc); exit(-1); } } // 等待所有线程完成 for(t=0; t<NUM_THREADS; t++){ pthread_join(threads[t], NULL); printf("\n\n"); } printf("SON\n"); for(i=0; i<800; i++) printf("%d\n", sayilar[i]); printf("\n\n"); FILE *yaz; //dosya göstericisi yaz = fopen("son.txt", "w+"); if(yaz == NULL){ puts("Dosya acilmiyor"); exit(1); } for(i=0; i<800; i++){ fprintf(yaz, "%d\n", sayilar[i]); } fclose(yaz); pthread_exit(NULL); } void *Sirala(void *param){ int i, baslangic, bitis; if((long)param ==0){ baslangic = 0; bitis= 300; kontrol =1; printf("Dizinin ilk 300 elemanının sırasız hali:\n\n"); for(i=baslangic; i<bitis; i++){ printf("%d - ", sayilar[i]); } printf("\n\n"); // 排序前300个元素 quickSort(sayilar, baslangic, bitis-1); printf("Dizinin 300 elemanının sıralı hali:\n\n"); for(i = baslangic; i<bitis; i++){ printf("%d - ", sayilar[i]); } } else if((long)param ==1){ baslangic = 300; bitis= 800; kontrol =2; printf("Dizinin diğer 500 elemanının sırasız hali:\n\n"); for(i=baslangic; i<bitis; i++){ printf("%d - ", sayilar[i]); } printf("\n\n"); // 排序后500个元素 quickSort(sayilar, baslangic, bitis-1); printf("Dizinin diğer 500 elemanının sıralı hali:\n\n"); for(i = baslangic; i<bitis; i++){ printf("%d - ", sayilar[i]); } } else { // 合并两个有序序列 merge(sayilar, 0, 299, 799); printf("合并后的完整有序数组:\n\n"); for(i = 0; i < 800; i++){ printf("%d - ", sayilar[i]); } } printf("\n\n"); pthread_exit(0); } void quickSort(int a[], int sol, int sag){ int j; if(sol<sag){ j=partition(a,sol, sag); quickSort(a, sol, j-1); quickSort(a, j+1, sag); } } int partition(int a[], int sol, int sag){ int pivot, i, j, t; pivot = a[sol]; i= sol; j= sag+1; do { do i++; while(a[i] < pivot && i <= sag); do j--; while(a[j] > pivot); if(i < j){ t = a[i]; a[i] = a[j]; a[j] = t; } } while(i < j); t = a[sol]; a[sol] = a[j]; a[j] = t; return j; } void merge(int arr[], int left, int mid, int right) { int i, j, k; int n1 = mid - left + 1; int n2 = right - mid; int L[n1], R[n2]; for (i = 0; i < n1; i++) L[i] = arr[left + i]; for (j = 0; j < n2; j++) R[j] = arr[mid + 1 + j]; i = 0; j = 0; k = left; while (i < n1 && j < n2) { if (L[i] <= R[j]) { arr[k] = L[i]; i++; } else { arr[k] = R[j]; j++; } k++; } while (i < n1) { arr[k] = L[i]; i++; k++; } while (j < n2) { arr[k] = R[j]; j++; k++; } }
内容的提问来源于stack exchange,提问作者user9389953
相关产品推荐
相关产品推荐

