简体   繁体   中英

Minimum and Maximum of an array using pthreads in C

I'm having an issue with my code. Disclaimer btw, I'm new to C. Trying to learn it on my own. Anyways, I'm trying to get the minimum and maximum of an array. I broke the array into 4 parts to make 4 separate arrays and then used those 4 to pass in one of the parameters of each thread. With that being said, I'm only able to get the maximum for each part of the array and not the minimum and I don't understand why.

I think we can simplify your code, avoid all these unnecessary malloc calls, and simplify your algorithm for finding a min/max pair in an array.

Start by having a thread function that takes as input the following: an array (represented by a pointer), an index into the array from where to start searching on, and an index in the array on where to stop. Further, this function will need two output parameters - smallest and largest integer found in the array subset found.

Start with the parameter declaration. Similar to your MaxMin, but has both input and output parameters:

struct ThreadParameters
{
    // input
    int* array;
    int start;
    int end;

    // output
    int smallest;
    int largest;
};

And then a thread function that scans from array[start] all the way up to (but not including) array[end] . And it puts the results of its scan into the smallest and largest member of the above struct:

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;
}

And while we are at it, use capitol letters for your macros:

#define THREAD_COUNT 4

Now you can keep with your "4 separate arrays" design. But there's no reason to since the thread function can scan any range of any array. So let's declare a single global array as follows:

#define ARRAY_SIZE 400
int arr[ARRAY_SIZE];

The capitol letter syntax is preferred for macros.

fillArray becomes simpler:

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

Now main, becomes a whole lot simpler by doing these techniques.:

  • We'll leverage the stack to allocate our thread parameter structure (no malloc and free)

  • We'll simply start 4 threads - passing each thread a pointer to a ThreadParameter struct. Since the thread won't outlive main , this is safe.

  • After starting each thread, we just wait for each thread to finish)

  • Then we scan the list of thread parameters to get the final smallest and largest.

main becomes much easier to manage:

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);

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM