2012-08-24 5 views
-1

많은 운영 체제에서 하나의 맵 파일을 메모리에 저장하고 지연없이 읽을 수 있습니다. 운영 체제가이 작업을 효과적으로 수행 할 수 있다면 썽크에서 정기적 인 포인터를 생성 할 수 있습니다.모든 운영 체제에서 응용 프로그램 프로그래머가 썽크로 포인터를 만들 수 있습니까?

모든 운영 체제에서 응용 프로그램 프로그래머가 자신의 썽크에서 포인터를 만들 수 있습니까?

운영 체제가 이미이 기능을 지원한다는 것을 알고 있습니다. 파이프를 만들고 메모리에 매핑하고 파이프에 프로세스를 연결하여이 기능을 수행하지 못하게하기 때문입니다. 너무 불가능하거나 불합리한 것처럼 보입니다.

이 기능의 간단한 예는 역 참조 횟수를 계산하는 포인터입니다. 다음 프로그램은 0을 출력 한 다음 1을 출력합니다.

static void setter(void* environment, void* input) { 
/* You can't set the counter */ 
} 

static void getter(void* environment, void* output) { 
    *((int*)output) = *((int*)environment)++; 
} 

int main(int argc, char** argv) { 
volatile int counter = 0; 
volatile int * const x = map_special_voodoo_magic(getter, setter, sizeof(*x), 
                &counter); 

printf("%i\n", *x); 
printf("%i\n", *x); 

unmap_special_voodoo_magic(x); 
} 

P. x가 가리키는 값이 예기치 않게 변경되므로 휘발성 한정자가 필요합니까? 또한 컴파일러는 역 참조가 카운터를 변경한다고 생각할 이유가 없으므로 휘발성이 너무 필요합니다.

+2

'운영 체제가이 작업을 효과적으로 수행 할 수 있다면 효과적으로 썽크에서 정규 포인터를 만들 수 있습니다. '- 응? –

+0

@RobertHarvey 썽크는 느리게 평가되는 데이터 조각입니다. 메모리 매핑 된 파일은 느리게 읽혀집니다. 따라서 메모리 매핑 된 파일은 썽크 (thunks)의 스트림이고 거기에 포인터가 있습니다. –

+0

논리에 문제가 있습니다. 개가 사람의 가장 친한 친구라고 말하는 것과 비슷합니다. 모두에게 친구가 필요합니다. 그래서 모두에게 개가 있어야합니다. –

답변

1

다음 코드는 오류를 검사하지 않으며 완전한 구현이 아닙니다. 그러나 다음 코드는 썽크를 포인터로 만드는 기본 아이디어를 보여줍니다. 특히 값 4는 요청시 계산되며 메모리에 일찍 할당되지 않습니다.

#include <stdlib.h> 
#include <stdio.h> 
#include <sys/mman.h> 
#include <signal.h> 

void * value; 

static void catch_function(int signal, siginfo_t* siginfo, 
       void* context) { 
    if (value != siginfo->si_addr) { 
     puts("ERROR: Wrong address!"); 
     exit(1); 
    } 

    mmap(value, sizeof(int), PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED 
         | MAP_ANON, -1, 0); 

    *((int*)value) = 2 * 2; 
} 

int main(void) { 
    struct sigaction new_action; 

    value = mmap(NULL, sizeof(int), PROT_NONE, MAP_ANON | MAP_SHARED, -1, 
        0); 

    sigemptyset(&new_action.sa_mask); 

    new_action.sa_sigaction = catch_function; 
    new_action.sa_flags = SA_SIGINFO; 

    sigaction(SIGBUS, &new_action, NULL); 

    printf("The square of 2 is: %i\n", *((int*)value)); 

    munmap(value, sizeof(int)); 

    return 0; 
}