2013-06-03 2 views
0

내가 원하는 것은 다른 프로세스가 액세스 할 수 있도록 전역 공유 변수를 만드는 것입니다. 자식 프로세스를 기존 실행 파일로 대체하려고합니다.리눅스에서 다른 실행 파일 간의 공유 변수

업데이트 : 이것이 해결책이라고 생각합니다. 코드는 here에서 빌려 왔습니다. 그러나 모든 프로세스가 파일을 mmap하기 위해 최소한 하나의 I/O 작업이 필요하기 때문에 더 빠른 접근 방법이 있습니까?

mycode.h

static void* addr; //static 

app1.cc는

#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/mman.h> 
#include <fcntl.h> 
#include <sys/stat.h> 

int main(void) 
{ 
    size_t length = 1024 * 1024; 
    off_t offset = 0; 
    int prot = (PROT_READ| PROT_WRITE); 
    int flags = MAP_SHARED; 
    int fd = -1; 

    fd = open("./jim.mymemory", O_RDWR| O_CREAT, S_IRUSR| S_IWUSR); 
    if (fd == 0) { 
     int myerr = errno; 
     printf("ERROR: open failed (errno %d %s)\n", myerr, strerror(myerr)); 
     return EXIT_FAILURE; 
    } 

    addr = mmap(NULL, length, prot, flags, fd, offset); 
    if (addr == 0) { 
     int myerr = errno; 
     printf("ERROR (child): mmap failed (errno %d %s)\n", myerr, 
       strerror(myerr)); 
    } 
    *((int *) addr)=5; 
if (munmap(addr, length) == -1) { 
     int myerr = errno; 
     printf("ERROR (child): munmap failed (errno %d %s)\n", myerr, 
       strerror(myerr)); 
    }  
return 0; 
} 

이 mycode.cc

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/mman.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/wait.h> 
#include "mycode.h" 

int main(void) { 
    size_t length = 1024 * 1024; 
    off_t offset = 0; 
    int prot = (PROT_READ| PROT_WRITE); 
    int flags = MAP_SHARED; 
    int fd = -1; 
    pid_t pid; 

    fd = open("./jim.mymemory", O_RDWR| O_CREAT, S_IRUSR| S_IWUSR); 
    if (fd == 0) { 
     int myerr = errno; 
     printf("ERROR: open failed (errno %d %s)\n", myerr, strerror(myerr)); 
     return EXIT_FAILURE; 
    } 
    if (lseek(fd, length - 1, SEEK_SET) == -1) { 
     int myerr = errno; 
     printf("ERROR: lseek failed (errno %d %s)\n", myerr, strerror(myerr)); 
     return EXIT_FAILURE; 
    } 
    write(fd, "", 1); 

    if ((pid = fork()) == 0) { // child 
     /*Child process*/ 

     printf("INFO (child): start \n"); 
     execv("./app1", NULL); // **app1** 
     printf("INFO (child): done \n"); 

     msync(addr,sizeof(int),MS_SYNC|MS_INVALIDATE); // can be commented out, since we wait in the parent process 

    } else { 
     /*Parent process*/ 
     unsigned int readval = 0; 
     addr = mmap(NULL, length, prot, flags, fd, offset); 
     if (addr == 0) { 
      int myerr = errno; 
      printf("ERROR (parent): mmap failed (errno %d %s)\n", myerr, 
        strerror(myerr)); 
     } 

     printf("INFO (parent): start read\n"); 
     wait(NULL); 
     readval = *((int *) addr); 
     printf("val: %d \n", readval); 
     printf("INFO (parent): done read\n"); 

     if (munmap(addr, length) == -1) { 
      int myerr = errno; 
      printf("ERROR (parent): munmap failed (errno %d %s)\n", myerr, 
        strerror(myerr)); 
     } 
    } 

    if (close(fd) == -1) { 
     int myerr = errno; 
     printf("ERROR: close failed (errno %d %s)\n", myerr, strerror(myerr)); 
    } 
    unlink ("./jim.mymemory"); 
    return EXIT_SUCCESS; 
} 

이 어떤 도움에 감사드립니다 있습니다.

+1

익명 mmap을 만드는 대신 실제 파일을 사용할 수 있습니다. –

+0

@VaughnCato : 감사합니다. 그러나 이런 식으로 할 수 있겠는가?'struct Costume_Struct * my_struct;'그리고 나서'addr = mmap (NULL, length, prot, flags, fd, offset) 프로세스; Costume_Struct * proc_struct = (Costume_Struct *) addr' –

답변

2

execve은 커널의 모든 매핑을 삭제하므로이 기술은 작동하지 않습니다. 할 수있는 일은 파일을 열고 (Vaughn의 제안과 같이) 서술자을 자식 프로세스에 전달하는 것입니다. 열린 파일 디스크립터는 exec에서 변경되지 않습니다. 그런 다음 자식에 매핑 할 수 있습니다. 또는 shm_open()/shm_unlink()와 같은 API를 조사하여 글로벌 파일 매핑을 관리하여 다른 프로세스에서도 자식 만 사용할 수 있도록 할 수 있습니다.

기본적으로 : 아이에게 mmap()을해야합니다. 주소 공간에서 Unix의 자식에게 아무 것도 전달할 수 없습니다.

+0

고마워요. 하지만 구조를 공유하려면 어떻게해야합니까? 공유 파일에 텍스트로 구현해야합니까? 아니면 가능하다 :'struct Costume_Struct * my_struct;'그리고 나서'addr = mmap (NULL, length, prot, flags, fd, offset) 프로세스에서; Costume_Struct * proc_struct = (Costume_Struct *) addr'? –

+0

"UPDATE"를 참조하십시오 –

+2

예, 공유 메모리에 구조체 (C++ 객체는 "POD"인지 확인하는 데 큰주의를 기울이지 않아도 됨)를 넣을 수 있습니다. 그것은 당신이 생각하는대로 정확히 작동 할 것입니다; 그것은 단지 m emory입니다. –

관련 문제