pthread_join and void** - 错误理解

pthread_join and void** - error understanding

我写了一个简单的任务,如下所示。它打印一个字符串,递增全局变量 glob,并且 returns 它的值,通过 pthread_exit,到 pthread_join.

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

int glob = 0;

void *task()
{
    printf("I am a simple thread.\n");
    glob++;
    pthread_exit((void*)&glob);
}

int main()
{
pthread_t   tid;
int         create = 1;
void        **ppvglob;


    create = pthread_create(&tid, NULL, task, NULL);
    if (create != 0)    exit(EXIT_FAILURE);
    
    pthread_join(tid, ppvglob);
    
    int **ppv = (int**)ppvglob;
    printf("Variabile globale restituita alla terminazione del thread: %d\n", **ppv);                   
    
    return(0);
}

编译器给我错误:

main.c: In function ‘main’:
main.c:29:2: warning: ‘ppvglob’ may be used uninitialized in this function [-Wmaybe-uninitialized]
   29 |  pthread_join(tid, ppvglob);
      |  ^~~~~~~~~~~~~~~~~~~~~~~~~~

能告诉我原因吗?

做的时候:

pthread_join(tid, ppvglob);

因为你从未初始化过ppvglob编译器抗议是正常的,但实际上你必须更换:

void        **ppvglob;
....
pthread_join(tid, ppvglob);

作者:

void        *pvglob;
....
pthread_join(tid, &pvglob);

那么当然:

int **ppv = (int**)ppvglob;
printf("Variabile globale restituita alla terminazione del thread: %d\n", **ppv);                   

作者:

int *pv = (int*)pvglob;
printf("Variabile globale restituita alla terminazione del thread: %d\n", *pv);

所以有:

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

int glob = 0;

void *task()
{
    printf("I am a simple thread.\n");
    glob++;
    pthread_exit((void*)&glob);
}

int main()
{
  pthread_t   tid;
  int         create = 1;
  void        *pvglob;


  create = pthread_create(&tid, NULL, task, NULL);
  if (create != 0)    exit(EXIT_FAILURE);
    
  pthread_join(tid, &pvglob);
    
  int *pv = (int*)pvglob;
  printf("Variabile globale restituita alla terminazione del thread: %d\n", *pv);                   
    
  return(0);
}

编译执行:

% gcc -Wall c.c -lpthread
% ./a.out
I am a simple thread.
Variabile globale restituita alla terminazione del thread: 1

打印 1 因为这是 glob

的值

pthread_join() 有一个 void ** 参数,因为它需要 更新 一个 现有 void *.
这与向 scanf("%d", ...) 提供和 int * 的逻辑相同:要更新现有的 int,您需要提供其地址。
在一般情况下,当 C 函数必须更新现有的 Type 时, 那么它需要一个 Type * 参数。

无论如何,你不只是声明一个未初始化的Type *而是 提供现有 Type.
的地址 (&) 所以在这里,您需要获取现有 void * 的地址,以便 参数被初始化到 void * 实际所在的位置。

这里的想法是 void *...

void * glob;

...并将其 地址 传递给 pthread_join() 以便函数可以使其指向“return”值...

pthread_join(tid, &glob);

这个“让它指向 'return' 值”需要 pthread_join() 取消引用 它的参数...

*glob = /* whatever */;

...这样 您的 glob 就会改变它的值。

所做的是宣告...

void ** glob;

...这意味着您调用...

pthread_join(tid, glob);

... 会将 未初始化的 值传递给 pthread_join()(取消引用它是未定义的行为),也意味着您的 glob保持未初始化,使您的...

int **ppv = (int**)ppvglob;
printf("Variabile globale restituita alla terminazione del thread: %d\n", **ppv);                   

...还有未定义的行为。

这应该有效:

void * glob;

/* ... */

pthread_join(tid, &glob);

int * v = (int*)glob;
printf("Variabile globale restituita alla terminazione del thread: %d\n", *v);                   

(而且,拜托,拜托,不要使用 System Hungarian 符号...它太糟糕了,甚至微软停止使用它...)