2

我想在两个进程之间创建一个共享内存。我使用了叉子()。一个孩子试图改变这个共享的记忆,母亲创造了另一个孩子,所以新的孩子试图改变同样的记忆,依此类推。这是我在 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。为什么?我创建了一个共享内存。为什么父进程无法读取?

4

6 回答 6

6

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

你有两个选择,更简单和更难:

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

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

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

于 2009-12-26T16:51:40.337 回答
3

您有一个竞争条件,如果父母在孩子之前运行,并且您尝试在孩子放置任何东西之前访问 ch-> 怎么办?

您也只分配了 1 个字节(sizeof(char)),但您试图将其视为指向结构的指针 - 您需要为 mylist 分配足够的空间 - 除非您这样做更错误。您也需要 IPC_CREAT 标志来 shmget 某处。

于 2009-12-26T15:52:39.427 回答
1

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

您有两种方法可以解决此问题:

  1. 在 fork 之前设置共享内存。
  2. 让父母和孩子都打开相同的共享内存。

使用共享内存中的记录时,您需要确保该记录的所有数据都存在于共享内存中。例如,在这段代码中:

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

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

于 2009-12-26T16:42:11.323 回答
1

如果第一次运行父进程无法访问,ch->name因为 ch->name=ugur;还没有运行。我建议查看本教程以了解共享内存和此pdf 文件
我认为以前获得共享内存fork()并在孩子和父母中使用它的一种解决方案。

于 2009-12-26T15:58:36.170 回答
0

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

于 2013-03-15T19:22:40.957 回答
0

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

于 2009-12-26T18:42:16.230 回答