Как я могу управлять несколькими потоками в c с помощью pthread? - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь написать программу, которая может масштабироваться для использования динамического числа потоков pthreads на основе количества ядер для распараллеливания простого алгоритма. Алгоритм прост, он принимает целочисленный массив входных данных, и если каждое местоположение% 10! = 0, он хранит 0 в соответствующем местоположении выходного массива, в противном случае он хранит 10. Я не думаю, что проблема в том, что это такая простая проблема ... но я не понимаю, почему это не работает:

/*This variable is our reference to the child threads */
pthread_t childThreads[threadCount];

/*
...other setup code to initialize the parameters...
*/


/* create child threads*/
for(int i = 0; i< threadCount; i++)
{
    printf("running_P...\n");
    if(pthread_create(&(childThreads[i]), NULL, runParallelAlgorithm, (void *) &(parallelDataPakages[i])))
    {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }
}
/* join child threads*/
for(int i = 0; i< threadCount; i++)
{
    if(pthread_join(childThreads[i], NULL))
    {
        fprintf(stderr, "Error joining thread\n");
        return 2;
    }
    printf("not_running_P...\n");
}

и вывод этого:

running_P...
running_P...
running_P...
running_P...
not_running_P...
Error joining thread

Process returned 2 (0x2)   execution time : 0.047 s
Press any key to continue.

Я пытался посмотреть на другие решения, но похоже, что большинство людей пытаются использовать одну и ту же переменную pthread_t для создания потоков, в то время как у меня есть массив ... но он все еще не может присоединиться? Зачем? Я попытался сократить его только до соответствующего кода, но потому что я могу предоставить больше информации, если это необходимо.

Редактировать: Извините, я не предоставил достаточно информации. Фактическая программа составляет почти 200 строк, и я не хотел публиковать все это здесь изначально. Но если проблема не в этом разделе, я не уверен, что это вызывает эту проблему. Учитывая, что это не проблема, я свяжу суть с включенным кодом. Фактическое соединение, которое вызывает проблемы, находится на линии 140, извините, я не могу понять, что еще это было бы конкретно: https://gist.github.com/firestar9114/d77b72254d4ef93664fbda14a9ed1a19

Обновление: функция pthread_join() возвращает значение типа int, равное ESRCH, которое указано как "Не найден поток с идентификатором thread ". в руководстве. Я использую один и тот же массив childThreads[] для создания и присоединения к потокам, и я использую ту же переменную управления threadCount, которая всегда равна 4, поэтому я не понимаю, почему идентификатор потока не может быть найден ? Я попытался добавить оператор pthread_exit(NULL);, но он все еще не работает ... Есть идеи, связанные с этой новой информацией ???

1 Ответ

0 голосов
/ 10 ноября 2018

Вы ищете проблему в совершенно неправильном месте.

Основной причиной является переполнение буфера, здесь:

        /*advance the element pointer*/
        inputPointer = inputPointer + (sizeof(int) * elementsToProcess[i]);
        outputPointer = outputPointer + (sizeof(int) * elementsToProcess[i]);

Вы хотите продвинуться int *inputPointer и int *outputPointer на elementsToProcess[i]. Умножение на размер int является полностью фиктивным: увеличение или уменьшение указателя изменяет адрес на размер указанного типа, так что он указывает на следующий или предыдущий элемент в массиве. Итак, должно быть

        inputPointer = inputPointer + elementsToProcess[i];
        outputPointer = outputPointer + elementsToProcess[i];

или еще лучше,

        inputPointer += elementsToProcess[i];
        outputPointer += elementsToProcess[i];

По сути, ваш код перебирает другие данные, включая childThreads[] и метаданные внутреннего размещения библиотеки C.

...