2016-08-05 1 views
-1

OS가 32 bits입니다. 내가 만든 스레드는 4G보다 클 수있는 int 값을 반환합니다. 내 main() 함수에서이 값을 pthread_join()까지 어떻게받을 수 있습니까? 32 bits 시스템에서 보이는 것처럼 (void *)은 4 바이트입니다. 이와 같이Linux, C : 32 비트 OS에서 4G보다 greate 된 스레드에서 반환 값을 얻으려면 어떻게해야합니까?

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

void* thread_function(void) 
{ 
    uint64_t nbytes = 0; 
    //assign values to nbytes, it could be larger than 4G. 
    return (void *)nbytes; 
} 

int main() 
{ 
    pthread_t thread_id; 
    uint64_t nbytes; 

    pthread_create (&thread_id, NULL, &thread_function, NULL); 
    pthread_join(thread_id,(void**)&nbytes); 
} 
+1

현재 널 (NULL) arg로'& nbytes'를'pthread_create'로 보내고 단순히 함수의 주소를 통해 값을 캐스팅하고 설정하지 않으시겠습니까? – WhozCraig

+4

우선'thread_function'은 잘못된 타입입니다. 그것은 인수를 취해야합니다. 이제 어떻게 됐을까? 이 인수를 사용하여 값을 앞뒤로 전달할 수 있습니다. 그리고'void *'리턴 타입은 실제로 포인터가 아닌 타입으로 형변환되지는 않습니다. –

답변

2

:

void* thread_function(void *) 
{ 
    uint64_t nbytes = 0; 
    //assign values to nbytes, it could be larger than 4G. 

    void *retval = malloc (sizeof (nbytes)); 
    memcpy (retval, &nbytes, sizeof (nbytes)); 
    return retval; 
} 

int main() 
{ 
    pthread_t thread_id; 
    uint64_t nbytes; 

    pthread_create (&thread_id, NULL, &thread_function, NULL); 

    void *ret; 
    pthread_join(thread_id, &ret); 
    memcpy (nbytes, ret, sizeof (nbytes)); 
    free (ret); 
} 

이 다른 하나 개의 스레드에서 다른 값을 전송하기위한 공통 패턴이다. 보내는 쓰레드는 메모리를 할당하고, 값을 복사하고, 포인터를 전달합니다. 수신 스레드는 포인터를 가져 와서 값을 복사하고 포인터를 해제합니다.

+0

'thread_function' 서명이 유효하지 않습니다. 대안으로 (그리고 더 안전하다고 말할 것입니다) 접근 방법은 수신 스레드에서 미리 할당 된 버퍼에 대한 포인터를 가져 와서 채울 수 있습니다. 동일한 레벨에서 할당 코드와 해방 코드를 갖는 것이 훨씬 더 나은 방법입니다. –

+0

@EugeneSh. 고마워, 고쳐. 수신하는 쓰레드가 얼마나 큰 객체인지 알지 못하는 경우에도 스레드의 생성과 결합이 매우 다른 곳에서도 수행되기 때문에 이는 매우 표준적인 패턴입니다. 이 경우에는 결과가 생성되거나 소비되는 곳과 논리적으로 관련이 없기 때문에 할당을 스레드 생성에 연결하는 것이 더 나쁘다고 생각합니다. –

+0

글쎄, 그래. 알 수없는 객체 크기의 사용 사례는 완벽한 의미를 갖습니다. –

2

David Schwartz의 솔루션은 잘 알려져 있지만 단순한 정수를 넘기기에는 너무 어렵습니다. malloc()은 비싸지 만 반드시 스레드로부터 안전하지는 않습니다 (매우 희박하지만 오늘날 모든 포함 된 요소로 인해 & hellip;). 영업 이익에 처음 두 덧글의 아이디어를 따기

(WhozCraig 유진 쉿.)

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

void *thread_function(void *arg) 
{ 
    /* 
    No direct dereferencing 
     *arg = 0xdeadbeefcafe; 
    would give a compile error. With GCC it would be 

    threadargs.c:8:5: warning: dereferencing ‘void *’ pointer [enabled by default] 

    */ 
    uint64_t *nbytes = arg; 
    *nbytes = 0xdeadbeefcafe; 
    // you can return a simple status here, for example an error 
    return 0; 
} 

int main() 
{ 
    pthread_t thread_id; 
    uint64_t nbytes; 

    pthread_create(&thread_id, NULL, &thread_function, &nbytes); 
    pthread_join(thread_id, NULL); 
#define __STDC_FORMAT_MACROS 
#include <inttypes.h> 
    printf("nbytes = %" PRIx64 "\n", nbytes); 

    return 0; 
} 

은 어쩌면 더 나은 사용이 유형의 다른 방법으로 일을해야한다.

단점 : 모든 스레드는 자체 변수를 채우기를 원하기 때문에 고정 된 소량 스레드에 적합합니다. 그렇지 않으면 힙에서 할당하고 아무것도 얻지 못했고 그 반대의 경우도 있습니다. malloc()/free()을 모두 보류하기 위해 복잡합니다. David Schwartz의 방법은이 경우 훨씬 더 적절할 것입니다.

+0

POSIX 스레드를 사용한다면'malloc()'은 스레드로부터 안전합니다. –

+0

GlibC> = 2.2 (적어도 나는 더 일찍 생각한다.)하지만 나는 너무 자주 불타서 "당신이 얼마나 확실한 지 먼저 확인하는"힌트를주지 않았다. – deamentiaemundi

관련 문제