Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1322466
  • 博文数量: 482
  • 博客积分: 13297
  • 博客等级: 上将
  • 技术积分: 2890
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-12 16:25
文章分类

全部博文(482)

文章存档

2012年(9)

2011年(407)

2010年(66)

分类: LINUX

2011-03-28 09:24:18

我有一个问题,是关于fork的。我知道fork的作用是新开一个子进程,我现在的疑问是,内核是否会给fork开出的子进程单独初始化一个地址空间吗?子进程会否将父进程的地址空间中的数据拷贝到自己的地址空间中,如果不是的话,那么下面的理解是否正确。
fork开出的子进程是共享父进程的数据。但是当如果需要改变在父进程中定义的数据时,会使用copy on write机制进行修改。如果是这样的话,那么子进程在访问父进程中定义的数据时难道是直接访问父进程的地址空间?这样的话,如何做到地址空间的隔离?
  • [0]
  • [0]
回复次数:5
  • (波逐流)
  • 等 级:
#1楼 得分:5回复于:2011-03-06 21:24:35
我也是新手,简单说一下自己的理解:(不敢保证正确的)
fork创建子进程后,会将父进程的数据空间,堆栈空间都拷贝一份的,而不是像vfork一样共享父进程的。
  • [0]
  • [0]
精华推荐:
  • (nanbanshengxiaohong)
  • 等 级:
#2楼 得分:0回复于:2011-03-06 21:45:56
引用 1 楼 kuilong2010 的回复:
我也是新手,简单说一下自己的理解:(不敢保证正确的)
fork创建子进程后,会将父进程的数据空间,堆栈空间都拷贝一份的,而不是像vfork一样共享父进程的。


这也就是我疑惑的地方。我看的书(《Linux编程技术详解》)上说,fork是使用copy on write的,也就是说只有在试图改变的情况下子进程才会去做自己的一份copy,而如果像你所说的那样的话,那么将会出现资源浪费。
  • [0]
  • [0]
精华推荐:
  • (谭海燕 Linux C/C++)
  • 等 级:
  • 2

#3楼 得分:15回复于:2011-03-06 22:18:17
fork()之后,父进程中所有的数据都标记成只读。
从而fork出的子进程和父进程都能以读的访问数据。一旦需要写的时候,就会发生拷贝复制。

你你所说的地址空间隔离的问题完全不存在。

因为有虚拟地址的技术。
子进程中有 0x01地址,父进程中也有0x01地址,但是这两个0x01不是同一个地址。

这也就是虚拟地址空间。

子进程认为自己有4G的内存而感觉不到父进程的存在。

所以你所说的地址空间隔离的问题不存在
  • [1]
  • [0]
精华推荐:
  • (nanbanshengxiaohong)
  • 等 级:
#5楼 得分:0回复于:2011-03-08 14:11:57
引用 3 楼 feiyinzilgd 的回复:
fork()之后,父进程中所有的数据都标记成只读。
从而fork出的子进程和父进程都能以读的访问数据。一旦需要写的时候,就会发生拷贝复制。

你你所说的地址空间隔离的问题完全不存在。

因为有虚拟地址的技术。
子进程中有 0x01地址,父进程中也有0x01地址,但是这两个0x01不是同一个地址。

这也就是虚拟地址空间。

子进程认为自己有4G的内存而感觉不到父进程的存在。
……


太感谢您了。我理解了。

大致流程是这样的。其实对于虚拟地址空间来说,它只是起到一个假象的效果,因为最后在实现的时候有地址定位器之类的在后台将虚拟地址转换为实际内存地址。所以来说,子进程一开始在没有修改过这段数据前,看到的数据,只是假象在自己的虚拟地址空间中。这段虚拟地址最后映射到和父进程一样的内存中。一旦子进程试图改变这些变量时,就会触发copy-on-write,从而令os重新开辟一段内存存储新的数据,而将对应的虚拟地址空间的映射关系转移到那段物理地址上。

====

阅读(1056) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~