C中的部分螺纹排序

时间:2016-02-25 22:45:31

标签: c multithreading sorting

我试图用线程做部分排序, 我目前的输出

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;
}
你知道我哪里错了吗? 我认为它的结构,但我在网上看到的一切都做了我正在做的事情。

1 个答案:

答案 0 :(得分:2)

您正在将指向自动存储的指针传递给新创建的线程:一旦退出调用作用域,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);
    }