Linux内核学习—写时复制(COW)技术
写时复制技术(copy-on-write)
传统的Unix系统以一种比较统一的方式对待所有的进程:子进程复制父进程所有的资源。这种方法有一些很明显弊端:
- 将使用大量内存
- 复制操作耗费大量时间
- 通常情况下子进程不需要读或者写父进程拥有的所有资源,故该方法效率也是非常低的(复制的大量资源都没有使用)
并且,如果应用程序在进程复制后使用exec立即加载新程序,这意味着之前的复制基本是完全多余的,因为进程地址空间需要重新初始化,之前复制的数据不再需要,这导致之前做的都是无用功。
因此,现代Unix内核采用了写时复制(copy-on-write)机制避免fork时将父进程所有资源都复制到子进程。
该技术的核心思想是:只有在不得不复制内容时才去复制内容(tips:感觉操作系统中很多技术都是用到了该思想,如果一个操作的消耗比较大,那么就应该尽可能晚一点少一点该操作。例如:识别dirty bit的 extended clock页替换算法,还有很多操作系统在换页机制上均采用的是lazy换页,也就是不得不换页才换)
具体操作:当fork时只复制页表,因此fork之后父子进程的地址空间指向的是相同的物理内存页。如果父子进程都不需要修改彼此的页(也就是只读),则共享即可满足,因此将对应的页都标记为只读访问。只有两者中有一个进程要进行修改相应的物理页(也就是写操作),则会引发页错误。内核检测该页错误是否是因为对只读页面进行写操作引发的,如果是的话则处理该异常:拷贝该页面的内容到一个新的物理页,并设置其为可写,将新的物理页分配给正在写的进程,即修改该进程的页表中对应的这一页,重新执行写操作。
当一个用户父进程创建自己的子进程时,父进程会把其申请的用户空间设置为只读,子进程可共享父进程占用的用户内存空间中的页面(这就是一个共享的资源)。当其中任何一个进程修改此用户内存空间中的某页面时,内核会通过page fault异常获知该操作,并完成拷贝内存页面,使得两个进程都有各自的内存页面。这样一个进程所做的修改不会被另外一个进程可见了。
通过COW机制,使得内核可以尽可能地延迟内存页的访问,最重要的是,由于很多情况下并不需要写操作或只需要很少量的写操作,因此该机制将节省大量时间,提高效率。
实际上,Linux实现该机制时,对每个页描述符增添一个跟踪共享相应页框的进程数目的字段_count。
主要思路:首先判断缺页异常是否是因为访问内存中一个现有的页引起的,然后获取该页相应的页框描述符,只要判断该复制是否是有必要的(如果只有一个进程拥有这个页,就不需要复制,只需要将改页改为可写即可。如果有多个进程访问该页,则需要复制),如果需要复制则拷贝该页后修改要写进程的页表项。
Linux内核采用写时复制(Copy-On-Write, COW)技术来优化进程复制,避免不必要的内存和时间开销。在fork时仅复制页表,父子进程共享物理内存,只在写操作时触发页错误并复制页面,提高了效率。通过跟踪页描述符的计数字段,决定何时进行复制。"
103593315,5418167,PostgreSQL9.6主从复制配置详解,"['数据库管理', 'PostgreSQL', '高可用性', '复制配置', '故障转移']

8690

被折叠的 条评论
为什么被折叠?



