进程间通信,用共享内存出现问题。

炼气士 2012-08-22 10:41:46
这个共享内存,没有用shmid,是我自己的想法,也不知道哪里错了,无法实现父子进程间的通信。

我的理解是既然子进程复制了父进程的数据段,那么我通过传递指针来进行值传递不久可以了。

代码是这样的

int a = 1;
int b = 2;
int c = 3;
int *val[3];
val[0] = &a;
val[1] = &b;
val[2] = &c;
pid1 = fork();
switch(pid1)
{
case -1:
perror("fork error!");
exit(-1);
break;
case 0:
sleep(1);
//printf("a = %d\n", *val[0]);
printf("In child val[0] addr= %d, a=%d\n", (int)val[0], *val[0]);
exit(1);
break;
default:
*val[0] = 4;
printf("In parent val[0] addr= %d, a=%d\n", (int)val[0], *val[0]);
break;

}


运行的结果是:

In parent val[0] addr= -1076895948, a=4
In child val[0] addr= -1076895948, a=1

在父子进程中,val[0]的地址一样,但值却不一致;难道地址在内存空间不是唯一的吗?
请指点,谢谢!
...全文
290 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zairenjian_1 2012-08-25
  • 打赏
  • 举报
回复
堆栈是两份。逻辑地址一样,但它们映射的物理内存的地址是不一样的。
zairenjian_1 2012-08-25
  • 打赏
  • 举报
回复
堆栈是两份。逻辑地址一样,但它们映射的物理内存的地址是不一样的。
孤独小剑 2012-08-25
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

堆栈是两份。逻辑地址一样,但它们映射的物理内存的地址是不一样的。
[/Quote]
++
平凡的奋斗者 2012-08-24
  • 打赏
  • 举报
回复
我觉得是不是这样的, 子进程是因为父进程的fork()而创建,而又应为写时拷贝,子进程有了自己的代码数据,和堆栈,指针信息,但因为这写内容是从父进程拷贝过来的,所以和父进程的相同,包括指针的虚拟地址,但由于虚拟内存机制,虚拟地址相同,但是他们所指向的物理页面不同,所以,子进程所修改的值,不能反映到父进程中去,实际上楼主这样写达不到共享内存的目的。

当然,这只是个人见解,希望大牛指正。。。谢谢。。
平凡的奋斗者 2012-08-24
  • 打赏
  • 举报
回复
我觉得是不是这样的, 子进程是因为父进程的fork()而创建,而又应为写时拷贝,子进程有了自己的代码数据,和堆栈,指针信息,但因为这写内容是从父进程拷贝过来的,所以和父进程的相同,包括指针的虚拟地址,但由于虚拟内存机制,虚拟地址相同,但是他们所指向的物理页面不同,所以,子进程所修改的值,不能反映到父进程中去,实际上楼主这样写达不到共享内存的目的。

当然,这只是个人见解,希望大牛指正。。。谢谢。。
平凡的奋斗者 2012-08-24
  • 打赏
  • 举报
回复
我认为这里没有共享内存吧。

父进程只是通过fork()创建子进程。

而fork(),实际上是copy()了当前父进程的各种堆栈以及页表等等的很多信息,而此时子进程和父进程的区别就在于pid不同。

实际上,我认为,当子进程完成了写时拷贝以后,就有了自己的虚拟内存,但是由于没有执行exec()操作,所以子进程和父进程的当前执行的指令和指针所保存的虚拟内存值是相同的。

但是,由于子进程和父进程所指向的物理页面不同,所以虽然指针值相同,但是实际上所保存的地址是不同的,所以值也不同。

但是我也不知道我的理解是否正确,希望各位大牛指正啊。
ies_sweet 2012-08-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

副本和共享是两码事。
[/Quote]
++

楼主的表述还不是很清楚
两个进程之间的互斥问题楼主有处理吗?
如果没有处理,出现这个结果也是可能的
qq120848369 2012-08-23
  • 打赏
  • 举报
回复
副本和共享是两码事。
niceguy01 2012-08-23
  • 打赏
  • 举报
回复
看把你能得,在msdn中搜sharedmomery ,答案就在眼前。或者你搜索creatfileemapping,好像是这个 ,
Gonefar 2012-08-22
  • 打赏
  • 举报
回复
子进程复制了父进程的堆栈空间,只是共享文件描述字。
a的值不同,是由于父子进程可能都对a进行了操作,先后顺序不同,导致读入的值不同
赵4老师 2012-08-22
  • 打赏
  • 举报
回复
共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多,下面仅列出我现在能想到的:
·进程之间松耦合
·进程可在同一台机器上,也可跨机,跨操作系统,跨硬件平台,甚至跨国。
·方便调试和监视,只需让第三方或人工查看该临时文本文件即可。
·方便在线开关服务,只需删除或创建该临时文本文件即可。
·方便实现分布式和负载均衡。
·方便队列化提供服务,而且几乎不可能发生队列满的情况(除非硬盘空间满)
·……

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧