2016-10-02 6 views
0

pthread_join 함수를 사용하여 어제 문제가 발생했습니다. 오류가 발생했습니다. 인터넷에서 오랜 시간 동안 검색했지만 해결할 방법이 없습니다.왜 **를 사용하여 pthread_join의 반환 값을 얻을 수 없습니까

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 

나는 pthread_join의 반환 값을 얻기 위해 (&retval)를 사용하려고합니다. 그 retval이 void **에 속한다는 느낌이 들지만 (retval) 값을 얻을 수는 있지만 실패합니다. ** 포인터의 값을 얻기 위해 void을 사용할 수 없습니다. retval은 pthread_join에 의한 값이지만 ** retval을 사용하면 성공할 수 없습니다. ,

$ error:invalid use of void expression  
+0

사용'의 printf ("RETVAL = %의 LD \ 없음"(길이) RETVAL))'또는'의 printf ("RETVAL = % D \ n ", (int) retval)); ' – alk

답변

2

retvalvoid*입니다 pthread_join을

void *retval; 
... 
printf("retval=%ld\n",(long)**(&retval)); 
의 반환 값을 얻을 ** 사용할 수 없습니다

나는이 표시됩니다, GCC는 컴파일 사용 &retvalvoid**이므로 **(&retval)void입니다. 그런 다음 voidlong 번으로 캐스팅하려하지만 불가능합니다. 이것이 gcc : error:invalid use of void expression에서 얻은 이유입니다.

posix 스레드 시작 루틴은 void* 값을 반환해야합니다. say_hello()에는 필요에 따라 void*으로 올바르게 캐스팅 된 int (1)을 반환합니다.

pthread_join(pthread_t thread, void **value_ptr)은 두 번째 매개 변수로 결합 된 스레드의 반환 값을 저장하기위한 void*의 주소가 필요합니다. pthread_join(tid,&retval)을 호출하면 retval의 주소 인 pthread_join()void*이 올바르게 제공됩니다. 이렇게하면 스레드 반환 값 (void*)1retval에 저장됩니다. 다음과 같이이 작성했습니다 수

printf("retval=%ld\n",(long)retval); 

:

당신이 long에 주조 반환 값 retval을 인쇄하려면

이제 올바른 구문은 주석 하나입니다 많은 이해되지 않지만 상당

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

...

+0

void * 반환 값을 사용할 수있는 이유는 무엇입니까? void *는 주소입니다. 주소는 값을 저장할 수 있습니까? 나는 그것을 이해하지 못한다. – Marcos

+0

@Marcos :'void *'는 대개 메모리 주소를 나타내지 만 반드시 그런 것은 아닙니다. 함수'say_hello()'에서'int' (1)을'void *'에 캐스팅했는데,'void'를 사용하여'int' 값을 저장 했으므로 유효 메모리 주소를 나타내지 않습니다. 그래서 예, 포인터는 주소가 아닌 값을 저장할 수 있습니다. – shrike