进程
进程是一个正在执行程序的实例,是操作系统资源分配的基本单位,包括程序计数器,寄存器和变量的当前值,每个进程都有自己的虚拟CPU,实际上真正的CPU在各个进程之间来回切换。
正是由于其是资源分配的基本单位,所以当一个进程结束的时候,其所用的资源也都会被释放。像php-fpm 这种每个请求过来就创建一个进程,当请求处理完成,资源也就被释放了,这种模式下,无需担心如memory leak内存泄露的问题。php也有swoole这种常驻内存的模式,在swoole中使用一些php的第三方库,部分库的内存泄露问题就会被放大。
进程的调度:
一般都是时间片轮转,但时间片设得太短会导致过多的进程切换,降低了CU效率;而设得太长又可能引起对短的交互请求的响应时间变长。将时间片设为20~50ms通常是一个比较合理的折中。
线程
为什么需要线程?
1.线程比进程更轻量,一个线程通常有2M左右,一个进程通常有8M左右(暂时找不到之前看的哪个文章里面说的来佐证这个数据了),所以线程比进程创建更快,也更容易撤销。创建一个进程比创建一个线程要快10~100倍。
2.现在的计算机一般都是多核处理器,使用多线程能更大程度的发挥多核cpu的优势。
协程
协程就是用户态线程,可以看作是用户态线程包,因为其中又有很多个线程,即协程。内核对用户态线程包--协程一无所知,还是当成是普通的线程来管理。
用户空间需要有一个运行时系统以及一个线程表来管理协程,如果一个协程阻塞,就保存该协程的堆栈和寄存器信息,并在线程表中找出就绪态的协程,把可运行的协程的指令重新装入寄存器,就又可以继续运行。这样比陷入内核要快一个数量级,整个保存协程的状态和调度都是本地过程,要比进行内核调用效率更高,不需要上下文切换,也不需要对内存高速缓存进行刷新。
看着这种调度方式,和go的GMP调度也是差不多一个意思,就是GMP的具体实现更复杂一点。
纤程
纤程是windows中比线程更轻量的存在,纤程之间的切换开销要远远小于线程之间的切换。线程切换需要进出内核,而纤程之间的切换仅需要保存和恢复几个寄存器。
但是纤程很少使用。大多数的win32库完全不识别纤程,如果像实用线程一样使用纤程会遇到各种问题。由于内核不识别纤程,当一个纤程进入内核时,其所属线程可能阻塞,此时处理器会任意调度其他线程,导致该线程的其他纤程均无法运行。
评论区