fork的共享内存

时间:2009-12-26 15:44:11

标签: c unix memory fork shared

我想在两个进程之间创建一个共享内存。我用了fork()。一个孩子试图改变这个共享记忆,母亲创造另一个孩子,所以新孩子试图改变相同的记忆。这是我在C编程中的代码。 (ubuntu的)

mylist ch=NUL; 
f=fork();
if(!f){
        pba=shmget(KEYSHM,sizeof(char),0); /*created shared memory*/
        ch=(mylist *) shmat(pba,0,0);
        ch->name=ugur;
        ch->surname=cedric;
...do something...
}
else{
        if(ch)
        printf("this is top of mylist %s"ch->name);
.......do something
}

它永远不会写ch-> name。为什么?我创建了一个共享内存。为什么父进程无法读取?

6 个答案:

答案 0 :(得分:5)

对于要共享的内存,父和子都必须访问相同的共享内存。

你有两种选择,越简单越难:

  • 在分叉之前创建并附加到共享内存。父和子都可以自动访问相同的共享内存。

  • 先fork,然后父和子必须分别附加到共享内存。一旦进程分叉,它们就不再共享内存,特别是父进程中无法访问子进程中分配的任何内容。

您需要分配超过1个字符的共享内存来存储有用的字符串,例如名称。

答案 1 :(得分:3)

你有一个竞争条件,如果父母在孩子面前跑,你试图访问ch->在孩子放置任何东西之前?

你也只分配1个字节(sizeof(char)),但是你试图把它当作指向结构的指针 - 你需要为mylist分配足够的空间 - 除非你这么做得更好。你也需要IPC_CREAT标志在某处shmget。

答案 2 :(得分:1)

如果首次运行的父进程无法访问ch->name,因为ch->name=ugur;尚未运行。我建议您查看此tutorial以获取共享内存和此pdf file
一个解决方案,我认为在fork()之前获得共享内存并在子级和父级中使用它。

答案 3 :(得分:1)

你编写代码的方式,ch将指向一些共享内存,但ch本身(即指针)不会被共享。因为ch的赋值仅发生在子节点中,所以父节点将继续将ch视为NULL。

您有两种解决方法:

  1. 在fork之前设置共享内存。
  2. 让父母和孩子都打开相同的共享内存。
  3. 在共享内存中处理记录时,需要确保该记录的所有数据都存在于共享内存中。例如,在此代码中:

        ch->name=ugur;
        ch->surname=cedric;
    

    看来mylist :: name是一个char *。如果ch指向共享内存中的记录,则只会将指针放在共享内存中的名称中。除非您采取特定步骤将这些字符串放入共享内存中,否则它们将位于常规内存中,并且可能无法被其他程序访问。

答案 4 :(得分:0)

如果我在分叉之前创建并附加共享内存,那么我无法检查共享内存是否为NULL。它在附着时启动。

答案 5 :(得分:0)

您还为标志使用了0,它指定了访问权限以及是否应创建共享内存段等内容。换句话说,您没有给自己读取或写入访问权限,并且如果尚不存在则未指定要创建的段。