【问题标题】:Pthread_join returning variable value as 0Pthread_join 返回变量值为 0
【发布时间】:2020-08-15 08:26:45
【问题描述】:

我想在以下代码中插入 pthread_join 函数来终止我的线程并更新变量值。之后我的想法是创建一个变量来添加我从线程中获得的新值并将其打印出来。 我有以下代码,似乎工作正常,但我想直接更新变量 ab 没有任何额外的变量(我不想使用aux_somaaux_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);
}

提前致谢。

【问题讨论】:

    标签: c pthreads pthread-join


    【解决方案1】:

    您所做的大部分工作在实践中都很好,并且可以说是最佳的,这依赖于通过指针类型来回整数值的能力。这避免了管理指向对象的生命周期的需要,这可能是危险错误的来源。但是你的程序有严重的 UB,编译器显然用警告告诉你,然后你试图用强制转换来掩盖:

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

    转换为void ** 几乎总是错误的。

    在这里,您告诉pthread_joinvoid * 类型的对象存储在&amp;aux_multiplicacao(然后在&amp;aux_soma),但该地址的对象没有正确的类型(甚至大小, 通常)来存储这样的对象。相反,您需要:

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

    【讨论】:

    • 是的,我是这么认为的,但是我的老师按照我在此处发布的示例进行了操作,所以我认为我必须以相同的方式进行操作。我会问她是否接受这种方式它更正确。谢谢:)
    • 如果你的老师做了 void ** 演员,她在客观上是危险的错误,只是看起来很有效,如果它确实有效,真的很倒霉。
    【解决方案2】:

    问题中的代码是将ab的值传递给线程函数,然后通过pthread_join取回结果。更好的解决方案是将ab 的地址传递给线程函数。然后函数可以得到ab的初始值。并且函数可以直接更新ab的值。

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

    【讨论】:

    • 谢谢!这就是我要找的:)
    • @AlbertoVarandas 不客气,很高兴我能帮上忙 :)
    猜你喜欢
    • 2020-08-06
    • 2012-10-30
    • 2016-06-02
    • 1970-01-01
    • 2021-10-26
    • 2021-01-14
    • 2015-05-01
    • 2014-12-23
    • 1970-01-01
    相关资源
    最近更新 更多