【问题标题】:Shared memory for forkfork 的共享内存
【发布时间】:2010-12-30 03:16:22
【问题描述】:
我想在两个进程之间创建一个共享内存。我使用了叉子()。一个孩子试图改变这个共享的记忆,母亲创造了另一个孩子,所以新的孩子试图改变同样的记忆,依此类推。这是我在 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。为什么?我创建了一个共享内存。为什么父进程无法读取?
【问题讨论】:
标签:
c
unix
memory
fork
shared
【解决方案1】:
对于要共享的内存,父母和孩子都必须访问相同的共享内存。
你有两个选择,一个更简单,一个更难:
您需要分配超过 1 个字符的共享内存来存储有用的字符串,例如名称。
【解决方案2】:
你有一个竞争条件,如果父级在子级之前运行,并且你尝试在子级放置任何东西之前访问 ch-> 怎么办?
您也只分配了 1 个字节(sizeof(char)),但您试图将其视为指向结构的指针 - 您需要为 mylist 分配足够的空间 - 除非您这样做更错误。您还需要 IPC_CREAT 标志来 shmget 某处。
【解决方案3】:
如果第一次运行的父进程无法访问ch->name,因为ch->name=ugur; 尚未运行。我建议查看此tutorial 共享内存和此pdf file。
我认为在fork() 之前获得共享内存并将其用于孩子和父母的一种解决方案。
【解决方案4】:
按照您编写代码的方式,ch 将指向一些共享内存,但 ch 本身(即指针)不共享。因为 ch 的赋值只发生在 child 中,所以 parent 会继续将 ch 视为 NULL。
您有两种方法可以解决此问题:
- 在 fork 之前设置共享内存。
- 让父母和孩子都打开同一个共享内存。
使用共享内存中的记录时,您需要确保该记录的所有数据都存在于共享内存中。例如,在这段代码中:
ch->name=ugur;
ch->surname=cedric;
mylist::name 似乎是一个字符 *。如果 ch 指向共享内存中的一条记录,这只会将指向名称的指针放在共享内存中。除非您采取特定步骤将这些字符串放入共享内存中,否则它们将位于常规内存中,并且可能无法被其他程序访问。
【解决方案5】:
如果我在分叉之前创建并附加共享内存,那么我无法检查共享内存是否为 NULL。它在附加时启动。
【解决方案6】:
您还使用 0 作为标志,它指定访问权限以及是否应创建共享内存段等内容。换句话说,您没有给自己读或写访问权限,也没有指定要创建的段是否尚不存在。