我使用pthread_join函数在昨天遇到问题,它出现了complie错误,我在网上搜索了很长时间,但是没有解决它。
pthread_join.c:
#include <stdio.h>
#include <pthread.h>
void* say_hello(void* args)
{
printf("hello from thread\n");
pthread_exit((void*)1);
}
int main()
{
pthread_t tid;
int iRet=pthread_create(&tid,NULL,say_hello,NULL);
if(iRet)
{
printf("pthread create error:iRet=%n\n",iRet);
return iRet;
}
void *retval;
iRet=pthread_join(tid,&retval);
if(iRet)
{
printf("pthread_join error:iRet=%d\n",iRet);
return iRet;
}
printf("retval=%ld\n",(long)**(&retval));
// printf("retval=%ld\n",(long)retval);
return 0;
}
错误:
$ error:invalid use of void expression
我尝试使用(&retval)
获取pthread_join
的返回值。我认为retval属于void **,然后我使用(retval)应该可以获得值,但是失败了。我不能使用void 来获取**的值指针,我认为retval是pthread_join的值,但如果使用** retval来获取它,就不会成功。
我用gcc编译它,它会显示:
$ error:invalid use of void expression
答案 0 :(得分:2)
为什么不能使用**来获取pthread_join的返回值
void *retval;
...
printf("retval=%ld\n",(long)**(&retval));
retval
是void*
,&retval
是void**
,因此**(&retval)
是void
。然后,您尝试将void
投射到long
,这是不可能的。这就是你从gcc:error:invalid use of void expression
获得的原因。
posix线程启动例程必须返回类型void*
的值。在say_hello()
,您可以根据需要将int
(1)正确投放到void*
。
pthread_join(pthread_t thread, void **value_ptr)
需要void*
的地址来存储已连接线程的返回值。通过致电pthread_join(tid,&retval)
,您可以pthread_join()
正确地提供retval
void*
的地址。这样做,线程返回值(void*)1
存储在retval
。
现在,如果您要打印返回值retval
,并将其转换为long
,则您输入的语法正确:
printf("retval=%ld\n",(long)retval);
您也可以写如下:
printf("retval=%ld\n",(long)*(&retval));
这是相同的虽然没有多大意义......
答案 1 :(得分:0)
引用此评论:Why can't use ** to get return value of pthread_join这里是另一个答案。
此
...
pthread_exit((void*) 1);
}
可能导致陷阱状态,并导致不确定的行为。
因此在线程终止处返回值1
的正确方法是:
...
int * pi = malloc(sizeof *pi);
/* Add error checking an handling for malloc() here. */
*pi = 1;
pthread_exit(pi); /* No need to cast in C. */
}
在连接另一个线程的线程内执行:
...
{
void * pv;
pthread_join(..., &pv); /* Add error checking and handling for pthread_join(). */
printf("thread returned: %d\n", *((int*) pv));
free(pv); /* Free what the other thread allocated (see above). */
}
...