Pthread_join возвращает значение переменной как 0 - PullRequest
0 голосов
/ 30 апреля 2020

Я хочу вставить функцию pthread_join в следующий код, чтобы завершить мои потоки и обновить значение переменных. После этого моей идеей было создать переменную, чтобы добавить новые значения, полученные из потоков, и распечатать их. У меня есть следующий код, который, кажется, работает нормально, но я хочу обновить переменные a и b напрямую без каких-либо дополнительных переменных (я не хочу использовать aux_soma и aux_multiplicacao ). Если я попытаюсь обновить их напрямую, они получат значение 0 (в основном переменная a ). Есть ли способ сделать это так, как я хочу? Код написан на португальском языке, извините за это, надеюсь, вам все равно удастся его понять.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

void *soma(void *valor)
{
  int a = (intptr_t) valor;
  a = 10 + a;
  //printf("A thread soma terminou.\n");
  pthread_exit((void*)(intptr_t)a);
}

void *multiplicacao(void *valor)
{
  int a = (intptr_t) valor;
  a = 10 * a;
  //printf("A thread multiplicacao terminou.\n");
  pthread_exit((void *)(intptr_t)a);
}

int main()
{
  pthread_t p, t;

  int a = 5, b = 5;
  int aux_soma, aux_multiplicacao; // Variáveis auxiliares para evitar erros

  printf("\n\n"); // Duas linhas em branco; Para ficar separado e mais apresentável

  // Estava a dar erro no valor das variáveis e da soma, desta maneira não há erros
  int ra = pthread_create(&p, NULL, soma, (void *)(intptr_t)a);
  int rb = pthread_create(&t, NULL, multiplicacao, (void *)(intptr_t)b);
  pthread_join(t, (void **) &aux_multiplicacao);
  pthread_join(p, (void **) &aux_soma);

  a = aux_soma;
  b = aux_multiplicacao;

  int soma_ab = a + b;

  printf("\nIDthread soma = %d\n", (int) p);
  printf("IDthread multiplicacao = %d\n", (int) t);
  printf("a = %d\n", a);
  printf("b = %d\n", b);
  printf("Soma: a + b = %d\n", soma_ab);

  exit(0);
}

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 01 мая 2020

Практически все, что вы делаете, хорошо на практике и, возможно, оптимально, полагаясь на возможность округлять целочисленные значения через указатели. Это избавляет от необходимости управлять временем жизни указанного объекта, что может быть источником опасных ошибок. Однако в вашей программе есть серьезный UB, о котором, по-видимому, компилятор сообщил вам с предупреждением, и что вы затем попытались записать с помощью приведений:

pthread_join(t, (void **) &aux_multiplicacao);
pthread_join(p, (void **) &aux_soma);

Приведение к void ** почти всегда неверно .

Здесь вы говорите pthread_join хранить объект типа void * в &aux_multiplicacao (а затем в &aux_soma), но объект по этому адресу не имеет правильный тип (или даже размер, в общем) для хранения такого объекта. Вместо этого вам нужно:

void *tmp;
pthread_join(t, &tmp);
aux_multiplicacao = (intptr_t)tmp;
pthread_join(p, &tmp);
aux_soma = (intptr_t)tmp;
0 голосов
/ 01 мая 2020

Код в вопросе передает значение a и b в функцию потока, а затем извлекает результат через pthread_join. Лучшее решение - передать адрес a и b функциям потока. Тогда функции могут получить начальные значения a и b. И функции могут обновлять значения a и b напрямую.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *soma(void *valor)
{
    int *aptr = valor;
    int a = *aptr;    // get the initial value of 'a'

    a = 10 + a;       // do something with 'a'

    *aptr = a;        // set the final value of 'a'
    return NULL;
}

void *multiplicacao(void *valor)
{
    int *aptr = valor;
    int a = *aptr;    // get the initial value of 'a'

    a = 10 * a;       // do something with 'a'

    *aptr = a;        // set the final value of 'a'
    return NULL;
}

int main()
{
    int a = 5, b = 5;

    pthread_t p, t;
    int ra = pthread_create(&p, NULL, soma, &a);
    int rb = pthread_create(&t, NULL, multiplicacao, &b);
    if (ra != 0 || rb != 0)
        exit(1);
    pthread_join(t, NULL);
    pthread_join(p, NULL);

    int soma_ab = a + b;

    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("Soma: a + b = %d\n", soma_ab);
}
...