首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用多个线程的快速排序使最后的1/6未排序。

使用多个线程的快速排序使最后的1/6未排序。
EN

Stack Overflow用户
提问于 2020-04-11 00:27:17
回答 1查看 139关注 0票数 0

我的目标是创建一个程序,该程序包含大量未排序整数(1-10百万),并将其划分为6个部分,线程在其中并发地对其进行排序。排序之后,我将它合并成一个排序数组,这样我就可以更快地找到中间和模式。

输入文件如下所示:

代码语言:javascript
运行
复制
# 1000000
314
267
213
934

其中,#后面的数字标识列表中整数的数量。

目前,我可以在没有线程的情况下进行完美和快速的排序,然而,当我开始线程处理时,我遇到了一个问题。对于1,000,000个数据集,它只对前833,333个整数进行排序,留下最后的166,666 (1/6)个未排序的整数。

代码语言:javascript
运行
复制
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <time.h>
#define BUF_SIZE 1024

int sum; /* this data will be shared by the thread(s) */
int * bigArr;
int size;
int findMedian(int array[], int size)
{
    if (size % 2 != 0)
        return array[size / 2];

    return (array[(size - 1) / 2] + array[size / 2]) / 2;
}
/*compare function for quicksort*/
int _comp(const void* a, const void* b) {
    return ( *(int*)a - *(int*)b);
}

/*This function is the problem method*/
/*indicate range of array to be processed with the index(params)*/
void *threadFct(int param)
{
    int x= size/6;
    if(param==0)x= size/6;
    if(param>0&&param<5)x= (size/6)*param;
    if(param==5)x= (size/6)*param+ (size%size/6);/*pass remainder into last thread*/
    qsort((void*)bigArr, x, sizeof(bigArr[param]), _comp);
    pthread_exit(0);
}

int main(int argc, char *argv[])
{
    FILE *source;
    int i =0;

    char buffer[BUF_SIZE];

    if(argc!=2){
        printf("Error. please enter ./a followed by the file name");
        return -1;}

    source= fopen(argv[1], "r");
    if (source == NULL) { /*reading error msg*/
        printf("Error. File not found.");
        return 1;
    }
    int count= 0;
    while (!feof (source)) {
        if (fgets(buffer, sizeof (buffer), source)) {
            if(count==0){  /*Convert string to int using atoi*/
                char str[1];
                sprintf(str, "%c%c%c%c%c%c%c%c%c",buffer[2],buffer[3],buffer[4],buffer[5],buffer[6],buffer[7],buffer[8],buffer[9],buffer[10]);/*get string of first */
                size= atoi(str); /* read the size of file--> FIRST LINE of file*/
                printf("SIZE: %d\n",size);
                bigArr= malloc(size*sizeof(int));
            }
            else{
                //printf("[%d]= %s\n",count-1, buffer); /*reads in the rest of the file*/
                bigArr[count-1]= atoi(buffer);
            }
            count++;
        }
    }

/*thread the unsorted array*/
    pthread_t tid[6]; /* the thread identifier */
    pthread_attr_t attr; /* set of thread attributes */

// qsort((void*)bigArr, size, sizeof(bigArr[0]), _comp);  <---- sorts array without threading
    for(i=0; i<6;i++){
        pthread_create(&tid[i], NULL, &threadFct, i);
        pthread_join(tid[i], NULL);
    }

    printf("Sorted array:\n");

    for(i=0; i<size;i++){
        printf("%i \n",bigArr[i]);
    }

    fclose(source);
}

因此,为了澄清问题函数在我的threadFct()中。为了解释函数正在做什么,param(线程号)标识要快速排序的数组中的哪个块。我将大小分成6个部分,因为它是偶数,其余的数字进入最后一块。例如,1,000,000个整数,我的前5/6排序为166,666,最后的1/6将排序剩余的(166670)。

我知道

即使对于一千万整数,

  • Multi-threading也不会加快速度,
  • ,这不是寻找中值/模式

的最有效方法。

感谢您阅读这篇文章,并感谢您的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-11 00:49:28

在每次调用qsort时,您都要对数组的开头进行排序。您只需要通过设置x来更改每个线程排序的元素数。您还将x设置为线程、01中的相同值。

您需要在每个线程的数组中计算一个偏移量,这就是size/6 * param。元素的数量将是size/6,除了最后一个块,它使用一个模数来得到剩余的部分。

正如注释中提到的,线程函数的参数应该是指针,而不是int。可以在指针中隐藏整数,但需要使用显式转换。

代码语言:javascript
运行
复制
void *threadFct(void* param_ptr)
{
    int param = (int)param_ptr;
    int start = size/6 * param;
    int length;
    if (param < 5) {
        length = size/6;
    } else {
        length = size - 5 * (size/6);
    }
    qsort((void*)(bigArr+start), length, sizeof(*bigArr), _comp);
    pthread_exit(0);
}

以及以后的

代码语言:javascript
运行
复制
pthread_create(&tid[i], NULL, &threadFct, (void*)i);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61150610

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档