C 中的部分线程排序



我正在尝试用线程进行部分排序,我当前的输出它

27 12 21 48 15 28 82 69 35 91 
13 82 33 35 46 5 35 28 87 95 
0 10 20 22 23 30 52 80 86 96 
3 8 42 53 67 70 70 71 75 79 
5 8 8 18 41 43 70 79 86 88 
10 51 56 60 65 84 87 91 94 99 
23 25 38 39 40 44 51 56 69 75 
20 21 25 29 29 38 66 71 73 96 
33 50 9 6 13 27 97 21 70 22 
3 4 6 6 7 15 34 59 63 70 

如您所见,我正在对其进行部分排序,我希望我的输出是这样的(最后没有合并)

12 15 21 27 28 35 48 69 82 91 
5 13 28 33 35 35 46 82 87 95 
0 10 20 22 23 30 52 80 86 96 
3 8 42 53 67 70 70 71 75 79 
5 8 8 18 41 43 70 79 86 88 
10 51 56 60 65 84 87 91 94 99 
23 25 38 39 40 44 51 56 69 75 
20 21 25 29 29 38 66 71 73 96 
6 9 13 21 22 27 33 50 70 97 
3 4 6 6 7 15 34 59 63 70 

我可以得到正确的输出,如果不是使用结构,而是使用 &array[i] 并手动输入长度

这是我到目前为止的代码:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pthread.h>
int cmpfunc(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}
struct values {
    int *arrayptr;
    int length;
};
void *thread_fn(void *a) {
    struct values *start = a;
    qsort(start->arrayptr, start->length, sizeof(int), cmpfunc);
    return (void*)a;
}
int main(int argc, const char *argv[]) {      
    FILE *fp = fopen(argv[3], "r");
    FILE *fp1 = fopen("numS1.dat", "w+");
    //amount of threads
    int threadAmount = atoi(argv[1]);
    //size of input
    int numberAmount = atoi(argv[2]);
    //multidimensional array
    int array[threadAmount][numberAmount / threadAmount];
    for (int i = 0; i < threadAmount; i++)
        for (int j = 0; j < numberAmount / threadAmount; j++)
            fscanf(fp, "%d", &array[i][j]);
    pthread_t threadid[threadAmount];
    for (int i = 0; i < threadAmount; ++i) {
        struct values a = { array[i], numberAmount / threadAmount };
        pthread_create(&threadid[i], NULL, thread_fn, &a);
    }
    for (int i = 0; i < threadAmount; ++i)
        pthread_join(threadid[i], NULL);
    for (int i = 0; i < threadAmount; i++) {
        if (i != 0)
            fprintf(fp1, "n");
        for (int j = 0; j < numberAmount / threadAmount; j++)
            fprintf(fp1 ,"%d ", array[i][j]);
    }
    return 0;
}

你知道我哪里出错了吗?我认为这是结构,但我在网上看到的一切都在做我正在做的事情。

您正在将指向自动存储的指针传递给新创建的线程:一旦退出调用范围,struct values 对象就会变得无效,因此新线程无法可靠地访问它。 您应该分配struct values并将指向已分配对象的指针作为参数传递给pthread_create

for (int i = 0; i < threadAmount; ++i) {
    struct values *a = malloc(sizeof(*a));
    a->arrayptr = array[i];
    a->length = numberAmount / threadAmount;
    pthread_create(&threadid[i], NULL, thread_fn, a);
}

线程函数可以在退出之前释放该结构。

笔记:

  • 将数组拆分为块的方式仅在长度是线程数的倍数时才有效。
  • 比较函数不适用于较大的int值,您应该改用这个:

    int cmpfunc(const void *a, const void *b) {
        return (*(int*)b < *(int*)a) - (*(int*)a < *(int*)b);
    }
    

最新更新