我知道這可能是一個奇怪的要求,但這里是:我必須在我的 x86-64 Linux ELF 可執行檔案中創建一個讀寫部分/段,以便該部分可以在行程及其子行程之間共享。我會處理緩沖區中的任何資料同步要求,所以請不要擔心這個麻煩。
我知道mmap可以將“共享”頁面映射到我的行程中,但由于某種原因,我不能使用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 部分,但發現它是私有的,我不知道是否以及如何使其共享?
$ ./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 手冊中有一個“共享”屬性,但它適用于 Windows,在 Linux 中編譯時會被忽略并發出警告。
uj5u.com熱心網友回復:
我知道 mmap 可以將“共享”頁面映射到我的行程中
是的,請使用mmap. 其他可能的答案:POSIX 共享記憶體(shm_open和朋友)和 SysV IPC(shmat和朋友)。
但由于某種原因,我不能使用 mmap 或類似功能。
您最好弄清楚“某種原因”是什么,因為您剛剛禁止了可行的解決方案。
我能做的是使用一個大字符陣列。到目前為止,我不知道這是否是一項不可能完成的任務。
那是行不通的。您目前只能共享“大字符陣列” fork()。一旦你有兩個獨立的行程,就不可能通過這個陣列進行進一步的通信。
uj5u.com熱心網友回復:
您可以嘗試通過閱讀/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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/463855.html
