2014-05-14 5 views
0

FILE 포인터 (FILE * rt_file)를 공유하기 위해 공유 메모리 (POSIX)를 사용하고 있지만 클라이언트 쪽에서 파일 포인터를 가져 오지 않았습니다. 어떤 제안을하시기 바랍니다.공유 메모리 (POSIX SKIN)를 사용하여 FILE 구조를 전송하는 방법

/* 
* shm_msgserver.c 
* 
* Illustrates memory mapping and persistency, with POSIX objects. 
* This process produces a message leaving it in a shared segment. 
* The segment is mapped in a persistent object meant to be subsequently 
* open by a shared memory "client". 
* 
* 
* Created by Mij <[email protected]> on 27/08/05. 
* Original source file available at http://mij.oltrelinux.com/devel/unixprg/ 
* 
*/ 


#include <stdio.h> 
/* shm_* stuff, and mmap() */ 
#include <sys/mman.h> 
#include <sys/types.h> 
/* exit() etc */ 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
/* for random() stuff */ 
#include <stdlib.h> 
#include <time.h> 


/* Posix IPC object name [system dependant] - see 
http://mij.oltrelinux.com/devel/unixprg/index2.html#ipc__posix_objects */ 
#define SHMOBJ_PATH   "/foo1423" 
/* maximum length of the content of the message */ 
#define MAX_MSG_LENGTH  50 
/* how many types of messages we recognize (fantasy) */ 
#define TYPES    8 

/* message structure for messages in the shared segment */ 
struct msg_s { 
    int type; 
    char content[MAX_MSG_LENGTH]; 
    FILE *pt; 
}; 


int main(int argc, char *argv[]) { 
    int shmfd; 
    int shared_seg_size = (1 * sizeof(struct msg_s)); /* want shared segment capable of storing 1 message */ 
    struct msg_s *shared_msg;  /* the shared segment, and head of the messages list */ 

    FILE *rt_file; 
    rt_file = fopen ("res","a+"); 
    printf("rt_file : %s\n",rt_file); 
    /* creating the shared memory object -- shm_open() */ 
    shmfd = shm_open(SHMOBJ_PATH, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG); 
    if (shmfd < 0) { 
     perror("In shm_open()"); 
     exit(1); 
    } 
    fprintf(stderr, "Created shared memory object %s\n", SHMOBJ_PATH); 

    /* adjusting mapped file size (make room for the whole segment to map)  -- ftruncate() */ 
    ftruncate(shmfd, shared_seg_size); 

    /* requesting the shared segment -- mmap() */  
    shared_msg = (struct msg_s *)mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); 
    if (shared_msg == NULL) { 
     perror("In mmap()"); 
     exit(1); 
    } 
    fprintf(stderr, "Shared memory segment allocated correctly (%d bytes).\n", shared_seg_size); 


    srandom(time(NULL)); 
    /* producing a message on the shared segment */ 
    shared_msg->type = random() % TYPES; 
    snprintf(shared_msg->content, MAX_MSG_LENGTH, "My message, type %d, num %ld", shared_msg->type, random()); 
    shared_msg->pt = rt_file; 


    /* [uncomment if you wish] requesting the removal of the shm object  -- shm_unlink() */ 
/* 
    if (shm_unlink(SHMOBJ_PATH) != 0) { 
     perror("In shm_unlink()"); 
     exit(1); 
    } 
*/ 

    return 0; 
} 

클라이언트 코드

/* 
* shm_msgclient.c 
* http://mij.oltrelinux.com/devel/unixprg/#ipc__posix_shm 
* Illustrates memory mapping and persistency, with POSIX objects. 
* This process reads and displays a message left it in "memory segment 
* image", a file been mapped from a memory segment. 
* 
* 
* Created by Mij <[email protected]> on 27/08/05. 
* Original source file available at http://mij.oltrelinux.com/devel/unixprg/ 
* 
*/ 

#include <stdio.h> 
/* exit() etc */ 
#include <unistd.h> 
/* shm_* stuff, and mmap() */ 
#include <sys/mman.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
/* for random() stuff */ 
#include <stdlib.h> 
#include <time.h> 


/* Posix IPC object name [system dependant] - see 
http://mij.oltrelinux.com/devel/unixprg/index2.html#ipc__posix_objects */ 
#define SHMOBJ_PATH   "/foo1423"  
/* maximum length of the content of the message */ 
#define MAX_MSG_LENGTH  50 
/* how many types of messages we recognize (fantasy) */ 
#define TYPES    8 

/* message structure for messages in the shared segment */ 
struct msg_s { 
    int type; 
    char content[MAX_MSG_LENGTH]; 
    FILE *pt; 
}; 



int main(int argc, char *argv[]) { 
    int shmfd; 
    int shared_seg_size = (1 * sizeof(struct msg_s)); /* want shared segment capable of storing 1 message */ 
    struct msg_s *shared_msg;  /* the shared segment, and head of the messages list */ 

    FILE *rt_file; 
    /* creating the shared memory object -- shm_open() */ 
    shmfd = shm_open(SHMOBJ_PATH, O_RDWR, S_IRWXU | S_IRWXG); 
    if (shmfd < 0) { 
     perror("In shm_open()"); 
     exit(1); 
    } 
    printf("Created shared memory object %s\n", SHMOBJ_PATH); 

    /* requesting the shared segment -- mmap() */  
    shared_msg = (struct msg_s *)mmap(NULL, shared_seg_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0); 
    if (shared_msg == NULL) { 
     perror("In mmap()"); 
     exit(1); 
    } 
    printf("Shared memory segment allocated correctly (%d bytes).\n", shared_seg_size); 
    rt_file = shared_msg->pt; 
    printf("rt_file : %s\n",rt_file); 
    rt_file = fopen ("res","a+"); 
    printf("rt_file : %s\n", rt_file); 
    char x[10]="ABCDEFGHIJ"; 
    fwrite(x, sizeof(x[0]), sizeof(x)/sizeof(x[0]), rt_file); 
    printf("Message type is %d, content is: %s\n", shared_msg->type, shared_msg->content); 
    if(shm_unlink(SHMOBJ_PATH) == -1){ 
     printf("%s is used by another Process\n",SHMOBJ_PATH); 
     } 
     else{ 
      printf("Memory is freed\n"); 
      } 
    return 0; 
} 
+5

'FILE' 구조체는 당신이 알지 못하는 필드를 가진 불투명 한 구조체입니다 만, stdio 시스템이 처리하는 메모리를 가리키는 (버퍼링을위한) 포인터가 하나 이상 포함되어있을 가능성이 큽니다. 메모리가 공유 메모리에있을 수 없습니다. 예 : ['setbuf'] (http://en.cppreference.com/w/c/io/setbuf) 수동으로 버퍼를 설정하지만'FILE' 구조체는 공유 할 수없는 다른 데이터를 포함 할 수 있습니다. –

+5

'FILE' 구조체는 한 프로세스에서만 열린 파일을위한 것이지, 다른 프로세스는 같은 파일을 열지 않습니다. 동일한 파일 기술자, 심지어는 소켓이나 다른 "파일"과 같은 파일 기술자로 완전히 다른 파일을 열어 놓을 수도 있습니다. –

+1

* 할 수있는 일은 [프로세스간에 파일 설명자를 공유] (http://stackoverflow.com/questions/909064/portable-way-to-pass-file-descriptor-between-different-processes)이지만 stdio'FILE'을 공유 할 수 없습니다. –

답변

1

FILE* 포인터에만이 만들어진 과정에서 유효합니다.

다른 프로세스에서 포인터 값이나 포인터가 가리키는 구조체를 다른 프로세스로 전송할 수 있지만 정의되지 않은 동작이 호출됩니다.

동일한 컴퓨터의 다른 프로세스가 특정 파일에 액세스하도록하려면 파일 이름, 모드 및 오프셋을 다른 프로세스로 보내고 fopen을 호출하여 자신의 FILE* 구조를 만들도록하십시오.