我想在两个进程之间创建一个共享内存。我用了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。为什么?我创建了一个共享内存。为什么父进程无法读取?
答案 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。
您有两种解决方法:
在共享内存中处理记录时,需要确保该记录的所有数据都存在于共享内存中。例如,在此代码中:
ch->name=ugur;
ch->surname=cedric;
看来mylist :: name是一个char *。如果ch指向共享内存中的记录,则只会将指针放在共享内存中的名称中。除非您采取特定步骤将这些字符串放入共享内存中,否则它们将位于常规内存中,并且可能无法被其他程序访问。
答案 4 :(得分:0)
如果我在分叉之前创建并附加共享内存,那么我无法检查共享内存是否为NULL。它在附着时启动。
答案 5 :(得分:0)
您还为标志使用了0,它指定了访问权限以及是否应创建共享内存段等内容。换句话说,您没有给自己读取或写入访问权限,并且如果尚不存在则未指定要创建的段。