进程

进程是一个程序的实例

上面是最基本进程定义。就好比说当你双击txt文件,就开启了一个进程运行文本编辑器。当你再双击一下,就又开启了一个进程。这两个进程互不干扰,一个进程关闭或者崩溃,并不会导致另一个进程关闭。但是这两个进程拥有一个通信的接口,就是那个txt文件。这两个文本编辑器使用的同一个文件,这就又引申出另一个问题,进程间通信(IPC).

在举个例子程序是一系列指令的集合,就好比一个类,进程则是真正在执行这些指令的东西,就好比对象。

进程的特点

进程拥有一个独立的执行环境。进程之间互不干扰。它拥有自己栈,堆,code,静态文本,完全自给自足。所以说一个进程拥有独立的地址空间以及一个或者多个线程。

进程的创建

unix系统中,进程创建执行主要靠两个函数forkexec

先来看fork,这个函数用来创建进程,执行一次返回两次。返回0的则是子进程。下面是创建过程。

  1. 创建一个进程管理块(PCB),这个东西保存了进程的状态,以及PC,寄存器等等
  2. 创建一个新的地址空间
  3. 把父进程的所有内容都拷贝的新的地址空间中,包括codestackheapstatic data
  4. 从父进程那里继承一些执行环境,比如打开的文件之类的
  5. 通知调度器,这个新的进程已经准备好了

fock函数就是克隆了一份当前的进程。然后exec,执行一个新的程序。

  1. 填充程序信息到刚才创建地址空间
  2. 复制参数到内存
  3. 执行程序,状态变为start

现在才是创建了一个真正新的进程。Linux采用copy-on-write技术,也就是说当fork时,并不直接复制整个地址空间给子进程,而是先共享一个拷贝,直到需要写入时,才拷贝。避免了大量的不必要拷贝。

线程

A thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system. A thread is a component of a process. Multiple threads can exist within one process, executing concurrently and sharing resources such as memory, while different processes do not share these resources

上面这段来自维基百科的定义,清楚简介的定义了线程。翻译下就是说,线程就是一段代码的执行单元,可以直接被调度器调度。并且是进程的一部分,一个进程可拥有多个线程。
多个线程可以并行执行,共享堆,静态文本。但是每个线程拥有自己的栈。

线程比进程更加轻量级,也称之为轻量级的进程。

为什么需要线程

  • 创建线程比创建进程的代价要低,且更迅速
  • 清楚简洁的表示并行任务。大多数程序都拥有需要并发执行的任务,你可以简单的为每个任务创建一个线程,语义明确且好维护。
  • 并行让任务立即响应。大幅度改善用户体验。保持用户界面流畅
  • 提升多核处理器的效率。多个任务并行处理,能大大减少计算时间
  • 使I/O更加高效。一些线程等待I/O数据,另外的去计算

进程vs线程

  • 进程之间是互相独立的,而线程共享heap以及static code
  • 进程创建需要创建新的地址空间,而线程并不要求。所以创建线程比进程更便宜。
  • 一个进程可以拥有多个线程
  • 对于内容切换,线程比进程快很多

Reference

维基百科
《Operating Systems Principles and Practice》