c - 当进程使用 shm_open() 时,Linux 内核如何分配内存指针?

标签 c linux ipc shared-memory interprocess

我在 Linux 2.6 上,遇到一个奇怪的问题。我有 3 个并发进程(从同一个进程派生)需要获得 3 个不同的共享内存段,每个进程一个。每个进程都执行此代码(请注意“消息”类型是用户定义的)

    message *m;
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    ftruncate(fd, sizeof(message));
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    char messagename[16];
    snprintf(messagename, sizeof(messagename), "%p", m);
    char path[32] = "/dev/shm/";
    strcat(path, messagename);
    rename("/dev/shm/message", path);

让我稍微解释一下:我希望每个进程都分配一个包含消息的共享内存区域。为了确保另一个进程(消息接收方)可以访问同一个 shm,然后我将我的 shm 文件从“消息”重命名为以消息指针命名的字符串(这是因为接收消息的进程已经知道指针)。

但是,在执行程序时,我尝试打印(出于调试目的)每个进程在映射通过 shm_open 获得的 fd 时接收到的指针,我注意到它们都获得了相同的指针。这怎么可能?我想也许其他进程在第一个进程执行之后和它重命名段之前执行了 shm_open(),所以我也尝试通过使用进程共享互斥锁使这些代码行成为原子操作,但问题仍然存在。

如果有任何帮助或建议,我将不胜感激。

最佳答案

您的进程在 fork 时都以相同的地址空间布局开始,然后遵循非常相似的代码路径。因此,它们最终都具有相同的 m 值也就不足为奇了。

但是,一旦它们成为独立的进程,它们的地址空间就变得独立了,因此 m 具有相同的 value 并不意味着所有的 m 指向相同的东西。

此外,我不确定您在创建共享内存块后重命名 /dev/shm 条目的想法是否安全或可移植。如果你希望每个进程的共享内存块都有一个唯一的名字,为什么不根据进程ID(保证在给定的时间点是唯一的)命名并直接传递给shm_open,而不是去麻烦之后重命名它?

关于c - 当进程使用 shm_open() 时,Linux 内核如何分配内存指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5090173/

相关文章:

c - Notepad++ 和 stdint.h 类型

mysql - 0 io 密集型应用程序上的 iowait。我的cpu用了什么时间?

linux - 如何在 linux 中为 python 3 安装 poppler?

c - GDB + TUI + GNU Screen - 将 gdb 输出发送到不同的 screen

wcf - 使用 WCF 和 NetNamedPipeBinding 进行 IPC

c - 如何在C中读取格式化数据?

c - 使用 while 循环时的段错误

c - 用户创建的警告在 XCode 7.1 中不再起作用。还有其他选择吗?

linux - Linux 管道缓冲区有多少数据? linux 管道缓冲区大小可以配置吗?

python - python 脚本可以知道同一脚本的另一个实例正在运行......然后与之交谈吗?