我可以在 Linux 进程和分支子进程之间创建共享数据部分吗?
Can I create a shared data section in among a Linux process and forked sub-processes?
我知道这可能是一个奇怪的要求,但它是:
我必须在我的 x86-64 Linux ELF 可执行文件中创建一个读写 section/segment,以便该部分可以在进程及其子进程之间共享。我会处理缓冲区中的任何数据同步需求,所以请不要担心这个问题。
我知道 mmap
可以将 'shared' 页面映射到我的进程中,但由于某些原因,我不能使用 mmap
或类似的功能。我能做的是使用一个大 char
数组。到目前为止,我不知道这是否是不可能完成的任务。
这是我的测试代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
// reserve 20M bytes as JIT buffer
#define BUF_SIZE 20*1024*1024
char jit_buffer[BUF_SIZE] __attribute__((section(".buffer"), aligned(4096)));
int main()
{
printf("pid=%d\n\n", getpid());
printf(".main Start Address: %p\n", &main);
printf(".buffer Start Address: %p\n", jit_buffer);
getchar();
return 0;
}
gcc -o bssmap bssmap.c
执行后,查看.buffer段,只发现是private,不知道是否以及如何制作共享?
$ ./bssmap
pid=557836
.text Start Address: 0x564e9637f189
.buffer Start Address: 0x564e96383000
在另一个终端
$ cat /proc/557836/maps
564e9637e000-564e9637f000 r--p 00000000 08:02 7213494 bssmap
564e9637f000-564e96380000 r-xp 00001000 08:02 7213494 bssmap
564e96380000-564e96381000 r--p 00002000 08:02 7213494 bssmap
564e96381000-564e96382000 r--p 00002000 08:02 7213494 bssmap
564e96382000-564e97783000 rw-p 00003000 08:02 7213494 bssmap <-- 'private' but want 'shared'
顺便说一句,我知道 GCC 手册中有一个 'shared' 属性,但它是针对 Windows 的,在 Linux.[=18 中编译时将被忽略并发出警告=]
I know mmap can map 'shared' pages into my process
是,做使用mmap
。其他可能的答案:POSIX 共享内存(shm_open and friends) and SysV IPC (shmat 和朋友)。
but for some reason, I cannot use mmap or similar functions.
你最好弄清楚“某些原因”是什么,因为你刚刚不允许可以工作的解决方案。
What I can do is to use a big char array. So far, I don't know if this is a mission impossible.
那 不会 工作。你只能在你 fork()
的时候分享“大字符数组”。一旦你有两个独立的进程,就不可能通过这个数组进行进一步的通信。
您可以尝试通过/proc/<pid>/mem
阅读,例如:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
// reserve 20M bytes as JIT buffer
#define BUF_SIZE 20*1024*1024
char jit_buffer[BUF_SIZE] __attribute__((section(".buffer"), aligned(4096)));
void read_mem(char *desc, int pid, off_t address)
{
int fd;
char memfile[32];
int val = 0;
snprintf(memfile, sizeof(memfile), "/proc/%d/mem", pid);
fd = open(memfile, O_RDONLY);
if (fd >= 0) {
if (pread(fd, &val, sizeof(val), address) == sizeof(val)) {
printf("%s value=%d\n", desc, val);
}
close(fd);
}
}
int main()
{
pid_t fid = getpid();
pid_t pid = fork();
if (pid < 0) {
printf("fork() failed!\n");
return 1;
} else if (pid > 0) {
*(int *)jit_buffer = 1;
usleep(100000);
read_mem("read child buffer:", pid, (long)jit_buffer);
wait(NULL);
} else {
*(int *)jit_buffer = 2;
usleep(200000);
read_mem("read parent buffer:", fid, (long)jit_buffer);
}
return 0;
}
我知道这可能是一个奇怪的要求,但它是: 我必须在我的 x86-64 Linux ELF 可执行文件中创建一个读写 section/segment,以便该部分可以在进程及其子进程之间共享。我会处理缓冲区中的任何数据同步需求,所以请不要担心这个问题。
我知道 mmap
可以将 'shared' 页面映射到我的进程中,但由于某些原因,我不能使用 mmap
或类似的功能。我能做的是使用一个大 char
数组。到目前为止,我不知道这是否是不可能完成的任务。
这是我的测试代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
// reserve 20M bytes as JIT buffer
#define BUF_SIZE 20*1024*1024
char jit_buffer[BUF_SIZE] __attribute__((section(".buffer"), aligned(4096)));
int main()
{
printf("pid=%d\n\n", getpid());
printf(".main Start Address: %p\n", &main);
printf(".buffer Start Address: %p\n", jit_buffer);
getchar();
return 0;
}
gcc -o bssmap bssmap.c
执行后,查看.buffer段,只发现是private,不知道是否以及如何制作共享?
$ ./bssmap
pid=557836
.text Start Address: 0x564e9637f189
.buffer Start Address: 0x564e96383000
在另一个终端
$ cat /proc/557836/maps
564e9637e000-564e9637f000 r--p 00000000 08:02 7213494 bssmap
564e9637f000-564e96380000 r-xp 00001000 08:02 7213494 bssmap
564e96380000-564e96381000 r--p 00002000 08:02 7213494 bssmap
564e96381000-564e96382000 r--p 00002000 08:02 7213494 bssmap
564e96382000-564e97783000 rw-p 00003000 08:02 7213494 bssmap <-- 'private' but want 'shared'
顺便说一句,我知道 GCC 手册中有一个 'shared' 属性,但它是针对 Windows 的,在 Linux.[=18 中编译时将被忽略并发出警告=]
I know mmap can map 'shared' pages into my process
是,做使用mmap
。其他可能的答案:POSIX 共享内存(shm_open and friends) and SysV IPC (shmat 和朋友)。
but for some reason, I cannot use mmap or similar functions.
你最好弄清楚“某些原因”是什么,因为你刚刚不允许可以工作的解决方案。
What I can do is to use a big char array. So far, I don't know if this is a mission impossible.
那 不会 工作。你只能在你 fork()
的时候分享“大字符数组”。一旦你有两个独立的进程,就不可能通过这个数组进行进一步的通信。
您可以尝试通过/proc/<pid>/mem
阅读,例如:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
// reserve 20M bytes as JIT buffer
#define BUF_SIZE 20*1024*1024
char jit_buffer[BUF_SIZE] __attribute__((section(".buffer"), aligned(4096)));
void read_mem(char *desc, int pid, off_t address)
{
int fd;
char memfile[32];
int val = 0;
snprintf(memfile, sizeof(memfile), "/proc/%d/mem", pid);
fd = open(memfile, O_RDONLY);
if (fd >= 0) {
if (pread(fd, &val, sizeof(val), address) == sizeof(val)) {
printf("%s value=%d\n", desc, val);
}
close(fd);
}
}
int main()
{
pid_t fid = getpid();
pid_t pid = fork();
if (pid < 0) {
printf("fork() failed!\n");
return 1;
} else if (pid > 0) {
*(int *)jit_buffer = 1;
usleep(100000);
read_mem("read child buffer:", pid, (long)jit_buffer);
wait(NULL);
} else {
*(int *)jit_buffer = 2;
usleep(200000);
read_mem("read parent buffer:", fid, (long)jit_buffer);
}
return 0;
}