进程与线程之间有什么区别

进程(process)是指在系统中正在运行的一个应用程序,是系统资源分配的基本单位,在内存中有其完备的数据空间和代码空间,拥有完整的虚拟空间地址。一个进程所拥有的数据和变量只属于它自己。

线程(thread)是进程内相对独立的可执行单元,所以也被称为轻量进程(lightweight processes)。线程是操作系统进行任务调度的基本单元,它与父进程的其它线程共享该进程所拥有的全部代码空间和全局变量,但拥有独立的堆栈(即局部变量对于线程来说是私有的)。

进程和线程都具有就绪、阻塞和运行三种基本状态。

联系

  • 一个进程至少拥有一个线程(主线程),也可以拥有多个线程
  • 一个线程必须有一个父进程,多个进程可以并发执行
  • 一个线程可以创建和撤销另一个线程
  • 同一个进程中的多个线程之间可以并发执行

区别

系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销
资源管理:进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

通信方式

进程间通信主要包括管道、系统IPC(包括消息队列,信号量,共享存储)、SOCKET,具体说明参考linux进程间通信方式。进程间通信其实是指分属于不同进程的线程之间的通讯,所以进程间的通信方法同样适用于线程间的通信。但对于同一进程的不同线程来说,使用全局变量进行通信效率会更高。

什么情况下适合使用线程

线程相对于进程的优势:

  • 线程间通信(数据交互)比进程间通信更加简便快捷。
  • 线程之间的上下文切换速度要比进程间的快,也就是说,对于操作系统而言,停止一个线程并启动另一个线程的速度比进程之间相似操作更快。
  • 创建一个线程的速度比创建一个进程的速度快。

下面的一些情景更适合使用线程来完成:

  • 进行耗时较长的处理:当一个windows界面程序正在计算时,它就不能处理其他消息(message)了,界面就不能及时更新。
  • 进行后台处理:有些任务并不是时间紧迫的,但是需要定期执行。
  • 进行 I/O 处理: I/O 操作或网络操作一般都会有一定的延迟,线程能保证程序中的其他部分不会受到延迟的影响。

什么情况下适合使用进程

进程相对于线程的优势:

  • 多线程系单进程的软件只能运行在一台机器上,而多进程的软件可以运行在多台机器上。这在一定程度上限制软件的可拓展性,单台机器的性能总是有限的。
  • 多进程模型的鲁棒性更好,有更好的容错性。运行在同一进程下的多个线程会相互影响,如果其中的一个线程出了问题,可能会波及整个进程。
  • 有些功能模块并不是线程安全的,这时就只能使用多进程模型了。

以chrome浏览器为例,它使用了多进程模型。每一个标签页都是一个进程,这样能够将渲染引擎中的bug隔离在该进程内,从而使整个程序免受影响。多进程模型将JavaScript隔离在每个进程中,这样就能防止其因占用过多的CPU或内存,使整个软件失去响应。另一方面,多进程模型的系统开销也是比较大的,这点能够从chrome的高额内存使用中看出来。不过chrome的优化策略可以让较低内存的情况下有更好内存使用效率。当一个标签页处于非激活状态,其对应的内存可以在需要时被交换进硬盘中,这样用户当前操作的页面就能够保持响应状态。如果使用的是多线程模型,区分活跃内存和非活跃内存就变得十分困难,导致内存使用效率的下降。