0

我想要做的是创建一个全局共享变量以供不同进程访问。我希望将子进程替换为现有的可执行文件。

更新:我认为这是解决方案。代码是从这里借来的。但是由于每个进程都需要至少一个 I/O 操作来映射文件,有没有更快的方法呢?

我的代码.h

static void* addr; //static

应用程序1.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;
}

我的代码.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;
}

任何帮助表示赞赏。

4

1 回答 1

3

execve将删除内核中的所有映射,因此该技术将不起作用。您可以做的是打开一个文件(如 Vaughn 的建议)并将描述符传递给子进程。打开文件描述符在 exec 中保持不变。然后你可以将它映射到孩子中。或者,研究像 shm_open()/shm_unlink() 这样的 API,它将管理全局文件映射,以便其他进程可以使用它,而不仅仅是子进程。

但基本上:您必须在孩子中使用 mmap(),您不能将地址空间中的任何内容传递给 Unix 中的孩子。

于 2013-06-03T04:03:48.603 回答