进程和线程

参考文献:    
  https://www.quora.com/What-is-the-difference-between-a-process-and-a-thread
  http://newsmth.net/nForum/#!article/CSArch/45612

进程与线程


虚拟内存和虚拟处理器是现代操作系统中最主要的两种虚拟抽象。对于一个运行的程序,这两者都提供了它独占系统资源的的假象。虚拟内存提供了程序从“内存”到物理RAM或者磁盘存储(swap space)上的无缝地址映射。而虚拟处理器则让程序以为它们单独享有一个处理器,而实际上多个程序是在多个处理器上多任务处理的。

进程是内存管理上的概念,线程是处理器管理上的概念。

进程是对一个运行的程序的抽象,是内存分配的最小单元,包括了 一个二进制映像,虚拟内存,内核资源,上下文等等。线程是一个程序中最小的执行单元,包括了逻辑处理器,栈,程序状态。一个进程可以包含一个或多个线程,因此,在一个进程内的多个线程共享一块内存地址空间。反过来,每个线程与不同的逻辑处理器相关联,是一个独立的调度实体。
每个进程有一个独立的虚拟地址空间,OS会在页表中有个总入口来遍历追踪这个进程的地址空间,cpu电路里有tlb来加速查找。一个进程里的多个线程就是多个执行路径,每个硬件单线程核心同一时刻只在执行同一个线程里的多条代码,每个硬件多线程核心同一时刻流水线里可能有多个线程的多条代码在执行。硬件多线程的目的就是充分将流水线填满,因为某个线程里的指令可能很多时候填不满流水线,比如访存等待,跳转排空等,此时由硬件自动载入另一个线程的指令利用这些空隙。cpu不管其正在执行的线程属于哪个进程。调度器按照优先级等规则轮番调度多个线程执行。

线程的引入为编程提供了以下一些优点:

  1. 编程抽象性:在很多问题中,我们都会将一个任务分成很多小块,再把每个小块安排给每一个执行单元(线程)。很多编程模式都利用了这一点,如reactor(反应器模式),thread-per-connection,线程池等。多线程给程序提供了更好的抽象性,但也有人认为
  2. 并行性:多核CPU时代,线程提供了一个非常有效地实现真正意义上的并行的方式。线程是一个独立的调度实体,并且拥有一个独立的逻辑处理器,因此,多个线程(并不一定属于同一个进程)可以同时运行再多个逻辑处理器上,提高系统处理效率。
  3. I/O阻塞:当I/O发生阻塞时,如果没有线程,进程会陷入长时间的等待。而在多线程程序内,等待的线程会进入睡眠状态,而其它的线程可以继续执行。异步和非阻塞I/O模型也是这种问题的一种解决方式。
  4. 节约内存:同一进程内的线程能高效地进行内存共享,相比于多进程能有效地节约内存空间。

多线程程序与多进程程序的优劣

  1. 线程比进程更轻量级,创建和撤销的代价小,内存、资源占用小。
  2. 线程的切换代价要比进程切换的代价小。
  3. 多线程再数据共享方面效率高很多,进程间通信需要通过信号,套接字,文件,管道等方式进行。反过来说,线程的数据共享也导致了在设计多线程程序时需要考虑同步锁,死锁等问题。
  4. 进程间相互隔离,稳定性更强。

用户级线程和内核线程的区别


内核线程是在操作系统内核中调度的,而用户级线程是在用户空间由程序本身进行调度的。通常情况下是作为一种语言特性提供的,如Golang的routine。

推荐阅读更多精彩内容