Linux下的进程和线程有什么区别?

概念

进程和线程有什么不同? 或者说有什么区别?
我们都知道: 进程是操作系统管理资源的最小单位, 线程是系统调度的基本单位.

那么具体到Linux系统, 进程和线程有什么区别呢?

首先, 在Linux Kernel看来, 其实是没有线程的. 所有的用户线程在在内核看来都是进程, 不过是轻量级的进程(Light Weight Process). 跟普通的进程有点区别. 区别在于:
轻量级进程之间共享同样的地址空间以及打开的文件等资源. 相比普通进程更轻量一些.

So, effectively we can say that threads and light weight processes are same.
It’s just that thread is a term that is used at user level while light weight process is a term used at kernel level.

实际上, 我们可以说线程和轻量级进程是一样的. 只是线程是一个用户级的术语, 而轻量级进程是一个内核级的术语.

实现

从实现的角度来看, 线程使用 pthread 库来创建. 它内部, 使用了 clone() 的系统调用来创建轻量级进程, 像创建普通进程一样. 这意味着创建一个普通进程的 fork() 函数, 后面也会调用 clone(), 根据创建线程或轻量级进程, 使用不同的参数.

所以进程和线程的主要不同, 就是调用 clone() 的传参不同.

系统调用 clone() 克隆一个任务, 带有一个可配置的共享级别, 它们是:

  1. CLONE_FILES: 共享同样的文件描述符表(而不是创建一个新的)
  2. CLONE_PARENT: 不在新任务和旧任务之间创建父子关系. 否则的话, 子进程的 getppid() = 父进程的 getpid()
  3. CLONE_VM: 共享同样的内存空间, 而不是复制一份.

fork() 调用 clone(), 最少的共享.
pthread_create() 调用 clone(), 最多的共享.

参考文献

  1. https://www.thegeekstuff.com/2013/11/linux-process-and-threads/
  2. https://stackoverflow.com/a/809049/2550332