为什么不能使用**来获取pthread_join的返回值

时间:2016-10-02 15:14:56

标签: c linux gcc pthreads pthread-join

我使用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       

2 个答案:

答案 0 :(得分:2)

  

为什么不能使用**来获取pthread_join的返回值

void *retval;
...
printf("retval=%ld\n",(long)**(&retval));

retvalvoid*&retvalvoid**,因此**(&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). */
  }     

  ...