Минимум и максимум массива с использованием pthreads в C - PullRequest
0 голосов
/ 06 декабря 2018

У меня проблема с моим кодом.Отказ от ответственности, кстати, я новичок в C. Пытаюсь изучить это самостоятельно.В любом случае, я пытаюсь получить минимум и максимум массива.Я разбил массив на 4 части, чтобы создать 4 отдельных массива, а затем использовал эти 4 для передачи одного из параметров каждого потока.Учитывая это, я могу получить максимум только для каждой части массива, а не минимум, и я не понимаю, почему.

1 Ответ

0 голосов
/ 06 декабря 2018

Я думаю, что мы можем упростить ваш код, избежать всех этих ненужных вызовов malloc и упростить ваш алгоритм для нахождения пары min / max в массиве.

Начнем с того, что функция потока, которая принимает в качестве входных данныхследующее: массив (представленный указателем), индекс в массиве, с которого нужно начать поиск, и индекс в массиве, где остановиться.Кроме того, для этой функции потребуются два выходных параметра - самое маленькое и самое большое целое число, найденное в найденном подмножестве массива.

Начните с объявления параметра.Аналогичен вашему MaxMin, но имеет как входные, так и выходные параметры:

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

    // output
    int smallest;
    int largest;
};

И затем функция потока, которая сканирует от array[start] до (но не включая) array[end].И он помещает результаты своего сканирования в smallest и largest член вышеупомянутой структуры:

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...