进程和线程,以及进程的Copy On Write究竟是什么意思

进程和线程

一谈到进程和线程的区别,很多人立马想到的是这样一句话:进程是操作系统资源分配的基本单位、而线程是任务调度和执行的基本单位。其实在操作系统看来,他们都是进程,而线程又被称为轻量级的进程。

进程

何为进程?在我看来,进程是由磁盘上的文件加载到内存后的信息以及其在内存运行时动态信息的组合。首先,我们的一个程序经过编译、链接之后变成了可执行文件ELF,而在一个程序看来,它是独占整个内存的,一个程序又分为代码段,数据段,堆区以及堆栈段。而这些代码数据等信息加载到内存之后,那么我得知道其真实得物理地址在哪把,还有我得知道这个程序(进程)在CPU运行了多长时间把,以及这个程序得运行状态等信息,这便是程序得动态信息,也即PCB(进程控制块),它由操作系统管理,而除此之外,每当操作系统切换进程得时候,我得知道调度得进程得寄存器的信息把,将这些信息从上一次中断之后返回到寄存器中,而保存这些信息在进程中叫做TSS,这是CPU的动态信息。在我看来,ELF静态信息,进程控制块,TSS等动态信息共同组成了进程。

线程

试想一下,当我们想要拷贝一个进程的时候,要考虑的问题是什么,第一,拷贝一个进程,那就是将进程中的代码段、数据段等等全部复制一遍。第二,进程切换的开销多大,进程切换首先得保存进程得上下文信息,寄存器的信息,PCB等等。然后把页表缓存TLB删掉,加载要切换进程的TLB。这个开销是比较大的。第三,进程之间的通信要怎么做,这个不用想,肯定很复杂!再这种情况下,线程就出现了!所谓的线程,就是共享进程中的地址空间,进程中的代码段,数据段都是共享的,而每个线程由自己的堆栈段。试想一下,上面的第一点可以完美解决,第二点,线程切换PCB是不变的,而TLB也不用更新。只不过线程共享数据,所以要考虑同步的问题。第三点,通信问题,因为线程是在同一个进程中,两个线程通信肯定比进程简单!

Copy On Write机制

那聊完了进程和线程,我们再来聊聊Copy On Write的原理,在Redis中,有一个RDB的持久化过程。RDB会把某一个时间点中Redis进程中的数据全部复制然后刷到磁盘中,那么问题来了,我真的要把Redis中的数据全部拷贝一边吗?你要想想假如现在Redis由5个G的数据,那我是不是要把这5个G的数据全部拷贝一边?这明显不合理。那么怎么做呢?想一想,我们是不是可以新起一个进程,然后这两个进程共享页表,也就是说数据都是一样的,那我是不是就不用拷贝了?那主进程如果修改了数据呢?那么我们可以把主进程指向数据的页在内存中重新拷贝一份,然后将主进程的页表修改重新指向新的页,而新起的子进程的数据没有被修改,还是RDB时候的数据,是不是很妙?这里用到的思想就是,Redis中的数据之后不可能全部都要修改的,我先让两个进程共享页表,当其中一个进程的数据改变的时候,我再来修改页表,这就提高了性能。当然,这个机制并不适用于频繁修改的场景,因为频繁的修改会导致缺页中断,从而性能急剧下降。

猜你喜欢

转载自blog.csdn.net/weixin_44821965/article/details/126776800
今日推荐