PS:http://blog.csdn.net/zxh821112/article/details/8969541

进程间是相互独立的,其实完全可以看成A、B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一份的。
然后在这个基础上,由于代码段是不会被修改的,所以操作系统可以采用copy on write的优化技术,让两个进程共享同一份物理内存。这是属于在不改变系统行为的基础上,为了节省内存,的优化技术。

COW技术初窥:

Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

那么子进程的物理空间没有代码,怎么去取指令执行exec系统调用呢?

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

在网上看到还有个细节问题就是,fork之后内核会通过将子进程放在队列的前面,以让子进程先执行,以免父进程执行导致写时复制,而后子进程执行exec系统调用,因无意义的复制而造成效率的下降。

COW详述:

现在有一个父进程P1,这是一个主体,那么它是有灵魂也就身体的。现在在其虚拟地址空间(有相应的数据结构表示)上有:正文段,数据段,堆,栈这四个部分,相应的,内核要为这四个部分分配各自的物理块。即:正文段块,数据段块,堆块,栈块。至于如何分配,这是内核去做的事,在此不详述。

1.      现在P1用fork()函数为进程创建一个子进程P2,

内核:

(1)复制P1的正文段,数据段,堆,栈这四个部分,注意是其内容相同。

(2)为这四个部分分配物理块,P2的:正文段->PI的正文段的物理块,其实就是不为P2分配正文段块,让P2的正文段指向P1的正文段块,数据段->P2自己的数据段块(为其分配对应的块),堆->P2自己的堆块,栈->P2自己的栈块。如下图所示:同左到右大的方向箭头表示复制内容。

2.       写时复制技术:内核只为新生成的子进程创建虚拟空间结构,它们来复制于父进程的虚拟究竟结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。

3.       vfork():这个做法更加火爆,内核连子进程的虚拟地址空间结构也不创建了,直接共享了父进程的虚拟空间,当然了,这种做法就顺水推舟的共享了父进程的物理空间

通过以上的分析,相信大家对进程有个深入的认识,它是怎么一层层体现出自己来的,进程是一个主体,那么它就有灵魂与身体,系统必须为实现它创建相应的实体, 灵魂实体与物理实体。这两者在系统中都有相应的数据结构表示,物理实体更是体现了它的物理意义。以下援引LKD

传统的fork()系统调用直接把所有的资源复制给新创建的进程。这种实现过于简单并且效率低下,因为它拷贝的数据也许并不共享,更糟的情况是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都将前功尽弃。Linux的fork()使用写时拷贝(copy-on-write)页实现。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。只有在需要写入的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。也就是说,资源的复制只有在需要写入的时候才进行,在此之前,只是以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候。在页根本不会被写入的情况下—举例来说,fork()后立即调用exec()—它们就无需复制了。fork()的实际开销就是复制父进程的页表以及给子进程创建惟一的进程描述符。在一般情况下,进程创建后都会马上运行一个可执行的文件,这种优化可以避免拷贝大量根本就不会被使用的数据(地址空间里常常包含数十兆的数据)。由于Unix强调进程快速执行的能力,所以这个优化是很重要的。这里补充一点:Linux
COW与exec没有必然联系

[转] Linux写时拷贝技术(copy-on-write)的更多相关文章

  1. Linux写时拷贝技术(copy-on-write)

    COW技术初窥: 在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内 ...

  2. 【转】Linux写时拷贝技术(copy-on-write)

    http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html 源于网上资料 COW技术初窥: 在Linux程序中,fork()会 ...

  3. Linux写时拷贝技术【转】

    本文转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/20/2601655.html COW技术初窥: 在Linux程序中,fork()会产 ...

  4. Linux写时拷贝技术(copy-on-write)

    1.传统的fork()函数创建一个子进程,子进程和父进程共享正文段,复制数据段,堆,栈到子进程示意图如下: 2.Linux的fork()函数-写时复制(copy-on-write)创建一个子进程,内核 ...

  5. copy-on-write(写时拷贝技术)

    今天看<Unix环境高级编程>的fork函数与vfork函数时,看见一个copy-on-write的名词,貌似以前也经常听见别人说过这个,但也一直不明白这究竟是什么东西.所以就好好在网上了 ...

  6. 写时拷贝(Copy On Write)方案详解

    本文旨在通过对 写时拷贝 的四个方案(Copy On Write)分析,让大家明白写时拷贝的实现及原理. 关于浅拷贝与深拷贝,我在之前的博客中已经阐述过了  浅拷贝容易出现指针悬挂的问题,深拷贝效率低 ...

  7. 【死磕 Java 基础】 — 谈谈那个写时拷贝技术(copy-on-write)

    copy-on-write,即写时复制技术,这是小编在学习 Redis 持久化时看到的一个概念,当然在这个概念很早就碰到过(Java 容器并发有这个概念),但是一直都没有深入研究过,所以趁着这次机会对 ...

  8. 写时拷贝COW(copy-on-write)

        写时拷贝技术是通过"引用计数"实现的,在分配空间的时候多分配4个字节,用来记录有多少个指针指向块空间,当有新的指针指向这块空间时,引用计数加一,当要释放这块空间时,引用计数 ...

  9. 关于Linux平台malloc的写时拷贝(延迟分配)【转】

    Linux内核定义了“零页面”(内容全为0的一个物理页,且物理地址固定),应用层的内存分配请求,如栈扩展.堆分配.静态分配等,分配线性地址后,就将页表项条目指向“零页面”(指定初始值的情况除外),这样 ...

随机推荐

  1. scrolView

    禁止UIScrollView垂直方向滚动,只允许水平方向滚动 scrollview.contentSize =  CGSizeMake(长度, 0); 禁止UIScrollView水平方向滚动,只允许 ...

  2. MySQL 选择数据库

    MySQL 选择数据库 在你连接到 MySQL 数据库后,可能有多个可以操作的数据库,所以你需要选择你要操作的数据库. 从命令提示窗口中选择MySQL数据库 在 mysql> 提示窗口中可以很简 ...

  3. android 9Path图片的使用

    Android UI设计时,经常会使用图片作为背景,比如给按钮设置背景图片时,图片会默认缩放来适应整个按钮.但是有时这种缩放效果并不是我们所需求的.而我们只是希望缩放图片的特定位置,以此来保证按钮的视 ...

  4. [C++] 对象地址与接口指针的故事

    刚想到一个问题,一直在思考C++中对象地址与接口指针的故事. 问题:多继承的情况下,一个具体类对象实现了多个接口,那么多该对象获取的不同接口指针是一样的吗?不是一样吗?不是对象地址吗?-- 困惑原因, ...

  5. 各种开源协议介绍 BSD、Apache Licence、GPL V2 、GPL V3 、LGPL、MIT

    现今存在的开源协议很多,而经过Open Source Initiative组织通过批准的开源协议目前有58种(http://www.opensource.org/licenses /alphabeti ...

  6. JQUERY1.9学习笔记 之基本过滤器(九) 小于选择器

    小于选择器 jQuery( ":lt(index)" ) jQuery( ":lt(-index)" ) 描述:选择所有小于指定下标的元素. <!DOCT ...

  7. JavaScript学习 常用的对话框函数

    JavaScript提供了三个很不错的对话框函数,使用这三个函数可以很方便的显示一个对话框: 一.alert(); <script type="text/javascript" ...

  8. python Template中substitute()的使用

    在python中Template可以将字符串的格式固定下来,重复利用. Template属于string中的一个类,要使用他的话可以用以下方式调用: from string import Templa ...

  9. 牛人总结python中string模块各属性以及函数的用法,果断转了,好东西

    http://blog.chinaunix.net/uid-25992400-id-3283846.html http://blog.csdn.net/xiaoxiaoniaoer1/article/ ...

  10. IOS--UIPageControl的使用方法详细

    IOS--UIPageControl的使用方法详细   // UIPageControl的常用方法 UIPageControl *onePageControl = [[UIPageControl al ...