如果子进程运行了 exec() 来加载另一个程序,如何在父进程和子进程之间共享内存?
通过创建的内存映射mmap()、通过获取的 POSIX 共享内存段shm_open()以及通过获取的 System V 共享内存段shmat()都不会在 exec 中保留。这涵盖了我所知道的 Linux 提供的所有形式的共享内存。
因此,如果您希望子级在 后与父级共享内存,exec()则子级必须在 后(重新)连接到适当的共享内存exec()。显然,这意味着必须exec()编写由 启动的任何程序来执行此操作。(特别注意,成功后,exec 系列函数不会返回。)
可以使用mmap吗?
仅当子进程在exec().
到目前为止,父级和子级使用 mmap 正确共享内存,但在 exec 完成后不会共享内存
这是设计使然。
您可以用来shm_open打开一个“命名”共享内存块,该内存块由文件系统上的文件标识。示例:在父级中:
int memFd = shm_open("example_memory", O_CREAT | O_RDWR, S_IRWXU);
if (memFd == -1)
{
perror("Can't open file");
return 1;
}
int res = ftruncate(memFd, /*size of the memory block you want*/);
if (res == -1)
{
perror("Can't truncate file");
return res;
}
void *buffer = mmap(NULL, /*size of the memory block you want*/, PROT_READ | PROT_WRITE, MAP_SHARED, memFd, 0);
if (buffer == NULL)
{
perror("Can't mmap");
return -1;
}
Run Code Online (Sandbox Code Playgroud)
在另一个文件中:
int memFd = shm_open("example_memory", O_RDONLY, 0);
if (memFd == -1)
{
perror("Can't open file");
return 1;
}
void *buffer = mmap(NULL, /*size of the memory block you want*/, PROT_READ, MAP_SHARED, memFd, 0);
if (buffer == NULL)
{
perror("Can't mmap");
return -1;
}
Run Code Online (Sandbox Code Playgroud)
在这些代码段之后就可以用来buffer访问共享内存了。(注意:它不需要是void*,您可以将其设置为指向您打算存储在共享内存中的任何内容的指针)