0%

The Difference between Process and Thread

对于操作系统而言,进程是整个现代操作系统的根本,操作系統是以进程为单位执行任务。随着技术发展,在执行一些细小任务,且本身无需分配单独资源时,进程的实现机制依然会繁琐的将资源分割,这样造成浪费,而且还消耗时间,所以就有了专门的多任务技术被创造出来——线程。 线程的特点就是在不需要独立资源的情况下就可以运行。如此一来会极大节省资源开销,以及处理时间。

进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

我们有如下对比图片:

Tables Process 进程 Thread线程
引入目的 可以并发执行,提高资源的利用率和系统吞吐量 调高并发执行的速度,进一步提高资源的利用率和系统吞吐量
并发性 较低 较高
基本属性(调度) 资源拥有的基本单位是进程,独立调度/分配的基本单位是进程 资源拥有的基本单位是进程,独立调度/分配的基本单位是线程
基本状态 就绪;执行;等待 就绪;执行;等待
系统开销 创建/撤销/切换时开销较大 创建/撤销/切换时开销较小
系统操作 创建;撤销;切换 创建;撤销;切换
存在状态 进程控制块PCB 进程控制块PCB,进程控制块TCB

但是对于 Linux 来说,它只支持轻量级进程,不支持线程,对于 Linux 而言:

  • 系统启动后的 第一个进程是 init,它的 PID 是 1。init 是唯一一个由系统内核直接运行的进程。
  • 除了 init 之外,每个进程都有 父进程(PPID 标识)
  • 每个进程还有四个 与用户和组相关的识别号
    1.实际用户识别号 (real user ID,RUID)
    2.实际组识别号 (real group ID,RGID)
    3.有效用户识别号 (effect user ID,EUID)
    4.有效组识别号 (effect group ID,EGID

######在 Linux 内核 2.4 版以前,线程的实现和管理方式就是完全按照进程方式实现的。在 2.6 版内核以后才有了单独的线程实现,为了弥补不支持线程的缺陷,Linux 引入线程组的概念,即该组中第一个轻量级进程的 PID,它被存入进程描述符的 tgid 字段中。getpid()系统调用返回当前进程的 tgid 值而不是 pid 值,因此,一个多线程应用的所有线程共享相同的 PID。

  • fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid),如果fork出错,返回一个负值.
  • fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。
  • fork()函数会把它所在语句以后的语句复制到一个子进程里,单独执行。
  • 如果printf函数最后没有"\n",则输出缓冲区不会被立即清空,而fork函数会把输出缓冲区里的内容也都复制到子进程里

  • 进程的执行过程是线状的,尽管中间会发生中断或暂停,但该进程所拥有的资源只为该线状执行过程服务。一旦发生进程上下文切换,这些资源都是要被保护起来的。

  • 线程的改变只代表了 CPU 执行过程的改变,而没有发生进程所拥有的资源变化。
  • 计算机内的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。
  • 进程拥有一个完整的虚拟地址空间,不依赖于线程而独立存在;反之,线程是进程的一部分,没有自己的地址空间,与进程内的其他线程一起共享分配给该进程的所有资源。
  • 线程中执行时一般都要进行同步和互斥,因为他们共享同一进程的所有资源。

文章来源:
进程和线程有哪些区别与联系?力扣(LeetCode)