两个进程在 exec 后共享内存

3

父级:

shm_id = shmget(IPC_PRIVATE, (1 << 16), IPC_CREAT | IPC_EXCL | 0777);
setenv("SOME_ENV_VAR",stringof(shm_id);
if(fork()=0){
    execve(some_path,argv);
}

孩子:

int shm_id = atoi(getenv("SOME_ENV_VAR"));
int *shared_mem = (int*)shmat(shm_id,0,NULL);
if(!shared_mem)
  return;
shared_mem[0]++;

我希望在子进程中编辑共享内存。有什么原因不能做到?我通过shmget在父进程中分配了共享内存块。我将shm_id作为环境变量放置在fork和exec后供子进程读取。
在子进程中,我正在读取正确的shm_id,然后尝试通过shmat获取指向共享内存的指针。在我的代码中,我已经验证了父进程和子进程中的shm_id是相同的... 有什么想法吗?

我在两个代码示例的每一行都看到至少一个错误,但代码的基本轮廓是正确的,除了你需要在父进程和子进程中都调用shmat(在fork之后执行此操作)。如果您需要更多帮助,请提供完整的程序,以便我们可以编译并运行它们,并告诉我们在运行它们时实际发生了什么,以及这不是您所期望的。 - zwol
1
注意:新程序应使用shm_open及其相关函数,而不是shmget及其相关函数。 - zwol
shmat() 调用应该是 shmat(shm_id, NULL, 0)。 - Aasim
@gblaster,你完成了这个任务吗?请告诉我,除了函数调用参数的混乱之外,你还遇到了什么问题。谢谢。 - Aasim
2个回答

2
< p > shmgetkey_t 参数与函数返回的标识符不同,将一个替换为另一个是不明智的。

但是,如果更改并通信 shmid 而不是 key,则基本方法将起作用。

shmid 是系统范围内的全局标识符,如果您具有适当的进程权限,则 shmat 将成功,即使您是不相关的进程。(而且,即使您是相关的,execve 也会分离任何共享内存段,需要显式重新连接。)

请注意,规范对此并不是非常明确,指出 "[每个共享内存段...应由称为共享内存标识符 shmid 的唯一正整数标识。"


假设调用成功,shmget 的返回值是一个“共享内存标识符”,这是传递给 shmat 的正确参数。然而,我不确定 POSIX/XSI 是否允许像 OP 这样跨进程边界序列化和反序列化“共享内存标识符”。它没有明确说明可以这样做,但也没有说不能。 - zwol
@zwol。在子进程中的shmat操作并没有失败。它试图给我一个有效的指针...当然,由于子进程现在拥有了新的进程地址空间,所以它与父进程不同,但我觉得这应该可以工作... - gblaster
@gblaster,我对你的问题发表的评论中所说的一切都坚持不变,唯独我现在不确定从一个进程传输shmget的返回值是否完全合法。但如果在子进程中shmat没有失败,那么这似乎不太可能是问题所在。 - zwol
@zwol 经过进一步阅读和测试,我认为这符合规范。回答已编辑。 - pilcrow

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接