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 符号...它太糟糕了,甚至微软停止使用它...)
我写了一个简单的任务,如下所示。它打印一个字符串,递增全局变量 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 符号...它太糟糕了,甚至微软停止使用它...)