Может кто-нибудь сказать мне ошибку, так как pthread_join не работает - PullRequest
0 голосов
/ 03 октября 2018
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct Array 
{
    //
};
void* evensum(void* param)
{
    //calculated the sum of even elements and returned it
}
void* oddsum(void* param)
{ 
  //did the same thing but for odd elements
}
int main()
{
    struct Array* obj=malloc(sizeof(struct Array));
    //did all the inputs
    int evensum,oddsum; 
    pthread_t thread1,thread2;
    pthread_create(&thread1,0,&evensum,(void*)obj);
    int evensum,oddsum;
    pthread_join(&thread,(void**)evensum);
    pthread_create(&thread2,0,&oddsum,(void*)obj);
    pthread_join(&thread2,(void**)oddsum);
    //try to print it using %i but I get or  %d 
    // I get the sum as zero
}

Итак, я создал два отдельных потока, и эти потоки должны были работать асинхронно.Я следовал совету, упомянутому здесь , но соединение по-прежнему не работает, так как как только поток1 завершает выполнение, другой поток никогда не создается, несмотря на то, что я придерживаюсь правильного синтаксиса.Есть идеи как это исправить?Кроме того, напечатанное значение равно нулю, несмотря на отображение правильного значения, если я напечатаю его в функции.Вот что я написал в операторе возврата каждой функции:

return (void*)sum;//variable that stores sum

Кроме того, я хочу добавить, что я не хочу использовать семафоры или любой другой инструмент синхронизации для этого.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Второй параметр для pthread_join является void **, то есть он ожидает указатель на void *, который он разыменовывает для сохранения значения. Поскольку вы не передаете адреспеременная, эта функция будет пытаться использовать любое значение, которое вы передали в качестве адреса (который, вероятно, будет недействительным), и разыменовать его.Это вызывает неопределенное поведение .

Кроме того, первый параметр имеет тип pthread_t, но вы передаете указатель на pthread_t.

Вы также объявляете локальные переменные с теми же именами, что и вызываемые вами функции.В результате, когда вы вызываете pthread_create(&thread2,0,&oddsum,(void*)obj);, вы фактически передаете локальную переменную int с именем oddsum, а не функцию с именем oddsum.Вот почему он зависает.

Изменение имени переменных для хранения результатов, изменение вызовов pthread_join для передачи адресов этих переменных и прямой передачи идентификаторов потоков должно работать:

int evenresult;
pthread_join(thread,(void**)&evenresult);
...
int oddresult;
pthread_join(thread2,(void**)&oddresult);

Однако правильным способом получения результата будет передача адресов действительных void * переменных и их преобразование:

int evenresult, oddresult;
void *result;
pthread_join(thread, &result);
evensum = (intptr_t)result;
...
pthread_join(thread2, &result);
oddsum = (intptr_t)result;
0 голосов
/ 03 октября 2018

Создайте все темы, а затем присоединитесь к ним, как показано ниже: -

pthread_create(&thread1,0,&evensum,(void*)obj);
pthread_create(&thread2,0,&oddsum,(void*)obj);

pthread_join(&thread1,(void**)evensum);
pthread_join(&thread2,(void**)oddsum);
...