如何使用共享内存(POSIX SKIN)传输FILE结构

时间:2014-05-14 12:57:57

标签: c file posix shared-memory file-descriptor

我正在使用共享内存(POSIX)来共享FILE指针(FILE * rt_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 <mij@bitchx.it> 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 <mij@bitchx.it> 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;
}

1 个答案:

答案 0 :(得分:1)

FILE*指针仅在创建它们的过程中有效。

虽然您可以将指针值或它指向的结构传递给另一个进程,但在另一个进程中使用它将调用未定义的行为。

如果您希望同一台计算机上的其他进程访问某个文件,我建议您将文件名,模式和偏移量发送给其他进程,并让它创建自己的FILE*结构致电fopen