在 C 中使用 pthread 的数组的最小值和最大值

Posted

技术标签:

【中文标题】在 C 中使用 pthread 的数组的最小值和最大值【英文标题】:Minimum and Maximum of an array using pthreads in C 【发布时间】:2019-05-07 20:48:54 【问题描述】:

我的代码有问题。免责声明顺便说一句,我是 C 的新手。试图自学。无论如何,我正在尝试获取数组的最小值和最大值。我将数组分成 4 个部分以创建 4 个单独的数组,然后使用这 4 个来传递每个线程的参数之一。话虽如此,我只能得到数组每个部分的最大值,而不是最小值,我不明白为什么。

【问题讨论】:

如果你真的在做 C,也就是说你使用了一个 C 编译器,那么就不需要所有这些强制转换了,所以放弃它们吧。 【参考方案1】:

我认为我们可以简化您的代码,避免所有这些不必要的 malloc 调用,并简化您在数组中查找最小/最大值对的算法。

首先有一个线程函数,该函数将以下内容作为输入:一个数组(由一个指针表示)、一个数组中的索引,从哪里开始搜索,以及一个数组中的索引在哪里停止。此外,此函数将需要两个输出参数 - 在找到的数组子集中找到的最小整数和最大整数。

从参数声明开始。与您的 MaxMin 类似,但同时具有输入和输出参数:

struct ThreadParameters

    // input
    int* array;
    int start;
    int end;

    // output
    int smallest;
    int largest;
;

然后是从array[start] 一直扫描到(但不包括)array[end] 的线程函数。并将其扫描结果放入上述结构的smallestlargest 成员中:

void* find_min_max(void* args)

    struct ThreadParameters* params = (struct ThreadParameters*)args;
    int *array = params->array;
    int start = params->start;
    int end = params->end;
    int smallest = array[start];
    int largest = array[start];


    for (int i = start; i < end; i++)
    
        if (array[i] < smallest)
        
            smallest = array[i];
        

        if (array[i] > largest)
        
            largest = array[i];
        
    

    // write the result back to the parameter structure

    params->smallest = smallest;
    params->largest = largest;

    return NULL;

当我们这样做的时候,为你的宏使用大写字母:

#define THREAD_COUNT 4

现在您可以继续使用“4 个单独的阵列”设计。但是没有理由因为线程函数可以扫描任何数组的任何范围。所以让我们声明一个全局数组,如下所示:

#define ARRAY_SIZE 400
int arr[ARRAY_SIZE];

大写字母语法是宏的首选。

fillArray 变简单了:

void fillArray()

    for (int i = 0; i < ARRAY_SIZE; i++)
    
        arr[i] = rand() % 1000 + 1;
    

现在 main,通过使用这些技术变得简单得多。:

我们将利用堆栈来分配我们的线程参数结构(无 malloc 和 free)

我们将简单地启动 4 个线程 - 将每个线程传递一个 指针 到 ThreadParameter 结构。由于线程不会超过main,因此这是安全的。

每个线程启动后,我们只是等待每个线程完成)

然后我们扫描线程参数列表,得到最终的最小和最大。

main 变得更容易管理:

int main()

    int smallest;
    int largest;

    // declare an array of threads and associated parameter instances
    pthread_t threads[THREAD_COUNT] = 0;
    struct ThreadParameters thread_parameters[THREAD_COUNT]  = 0;

    // intialize the array    
    fillArray();

    // smallest and largest needs to be set to something
    smallest = arr[0];
    largest = arr[0];

    // start all the threads
    for (int i = 0; i < THREAD_COUNT; i++)
    
        thread_parameters[i].array = arr;
        thread_parameters[i].start = i * (ARRAY_SIZE / THREAD_COUNT);
        thread_parameters[i].end = (i+1) * (ARRAY_SIZE / THREAD_COUNT);
        thread_parameters[i].largest = 0;
        pthread_create(&threads[i], NULL, find_min_max, &thread_parameters[i]);
    

    // wait for all the threads to complete
    for (int i = 0; i < THREAD_COUNT; i++)
    
        pthread_join(threads[i], NULL);
    

    // Now aggregate the "smallest" and "largest" results from all thread runs    
    for (int i = 0; i < THREAD_COUNT; i++)
    
        if (thread_parameters[i].smallest < smallest)
        
            smallest = thread_parameters[i].smallest;
        

        if (thread_parameters[i].largest > largest)
        
            largest = thread_parameters[i].largest;
        
    

    printf("Smallest is %d\n", smallest);
    printf("Largest is %d\n", largest);


【讨论】:

没有理由拥有int* array; int start; int end; - 而是拥有int *startsize_t length @AnttiHaapala - 同意。如果您想编辑答案以进行更改,我可以。鉴于他承认的经验水平,我的目标是让 OP 最容易阅读和摄取示例代码。 C 中的数组可能很难,因此我将其保留为“开始”和“结束”索引,因为它允许操作将线程函数视为扫描数组的特定 range,而不是引入更多指针数学概念.现在来看,这两种方式都可以解释。

以上是关于在 C 中使用 pthread 的数组的最小值和最大值的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 使用分而治之的方法查找未排序数组中的最小值和最大值

C pthread_barrier 同步问题

c语言利用数组指针方法 输入五个数字求出最小值 将最小值和数组第一个数字互换位置 输出数组

有没有办法读取 4 个不同的数组以在 C 的返回函数中生成最小值和最大值

c语言编程:输入一个五个元素的数组,输出这个数组的最大值,最小值和平均值

在数组中查找最小值和最大值