linux - Linux 中不同可执行文件之间的共享变量

标签 linux process fork mmap execv

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

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

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

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

感谢任何帮助。

最佳答案

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

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

关于linux - Linux 中不同可执行文件之间的共享变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16889705/

相关文章:

c# - 尝试概括身份验证(包括参数更改)

Perl fork 套接字服务器,当客户端断开连接时停止接受连接

c - 我的 switch 语句没有从 ​​for 循环中获取值

ruby - 为什么 fork 在 Minitest 测试中以非零退出?

linux - 如何配置 Vim 备份目录

c - 如何在特定界面上使用 cURL

linux - 在 Linux 中杀死后台进程

c++ - 对于网络映射驱动器形式的 C++ 代码,rsync 失败

Linux Terminal Nmap 同时映射多个 IP

linux - 堆叠多个 libnotify 弹出窗口