You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:45:34