文章目录
浅析进程与线程之间的区别
根本区别:进程是操作系统资源分配的基本单位,线程是操作系统调度的基本单位
- 每个进程都有独立的代码和数据空间,进程之间切换开销大;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器,线程之间切换的开销小。
- 进程之间拥有独立的虚拟内存地址空间和内核数据结构(页表,打开的文件描述符),当子进程修改了虚拟页之后,会通过写时复制(copy on write)创建真正的物理页。同一个进程中的线程之间共享进程的虚拟地址空间和内核数据结构,共享同样的物理页。
- 进程之间通信采用进程间通信的方式,管道,消息队列,信号量等。线程之间通信就比较简单,直接采用共享内存的方式,同一个进程下的不同线程共享一个虚拟内存地址空间,变量寻址采用同一个虚拟内存。
- 在操作系统中能同时运行多个进程(程序);而在同一个进程(程序)中有多个线程同时执行。一个进程执行失败不会影响其他进程,一个线程执行失败会导致整个进程执行失败,进程包含的其他线程也会执行失败。
- 进程采用fork创建,采用父子结构,复制父进程,线程采用clone创建,采用对等结构,共享父进程。复制的意思是会真正在物理内存复制一份内容,会真正消耗新的物理内存。共享的意思是使用指针指向同一个地址,不会真正的消耗物理内存。
从最普遍的答案出发
“进程是操作系统资源分配的基本单位,线程是操作系统调度的基本单位”,这句话可谓是最经典的答案,那么细究一下:
- 什么是计算机资源
- 什么是进程、线程
- 操作系统怎样给进程分配资源的
- 操作系统是怎样调度进/线程的
- 为什么需要线程
什么是计算机资源
从冯诺依曼结构来看,计算机资源可以简单的分为计算资源,存储资源,I/O设备资源
计算资源
简单的说就是CPU,CPU架构可以划分成3个模块,分别是控制单元、运算单元和存储单元,这三部分由CPU内部总线连接起来。
控制单元是整个CPU的指挥控制中心,包括指令寄存器IR(Instruction Register)、指令译码器ID(Instruction Decoder)和操作控制器OC(Operation Controller)、时序发生器和程序计数器等部件。
运算单元是核心组成部分,其包括执行算术运算和逻辑运算。相对控制单元而言,运算器接受控制单元的命令而进行动作,即运算单元所进行的全部操作都是由控制单元发出的控制信号来指挥的,所以它是执行部件。
存储单元包括CPU片内缓存和寄存器组,是CPU中暂时存放数据的地方。
存储资源
存储资源就是内存,磁盘这些存储设备的资源。操作系统使用了虚拟内存机制来管理存储器,从缓存原理的角度来说,把内存作为磁盘的缓存。进程是面向磁盘的,为什么这么说呢,进程表示一个运行的程序,程序的代码段,数据段这些都是存放在磁盘中的,在运行时加载到内存中。所以虚拟内存面向的是磁盘,虚拟页是对磁盘文件的分配,然后被缓存到物理内存的物理页中。所以存储资源是操作系统由虚拟内存机制来管理和分配的。
I/O设备资源
就是输入输出设备
什么是进程、线程
进程
进程是程序在某个数据集合上的一次运行活动,也是操作系统进行资源分配和保护的基本单位。通俗来说,进程就是程序的一次执行过程,进程是动态的,拥有其自己的生命周期, 新建,就绪,运行,阻塞,结束五大基本状态。
线程
是进程的一个执行单元,是进程内部调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
操作系统怎样给进程分配资源的
进程主要由进程控制块,数据段,程序段三个部分组成,其中进程控制块PCB是操作系统控制进程的重要数据结构,进程存在的唯一标识,是操作系统用来记录和刻画进程状态及环境信息的数据结构,也是操作系统掌握进程的唯一资料结构和管理进程的主要依据。
一般来说,PCB 会包含如下四类信息:
1)进程描述信息:用来让操作系统区分各个进程
- 当进程被创建时,操作系统会为该进程分配一个唯一的、不重复的 “身份证号”— PID(ProcessID,进程 ID)
- 另外,进程描述信息还包含进程所属的用户 ID(UID)
2)进程控制和管理信息:记录进程的运行情况。比如 CPU 的使用时间、磁盘使用情况、网络流量使用情况等。
3)资源分配清单:记录给进程分配了哪些资源。比如分配了多少内存、正在使用哪些 I/O 设备、正在使用哪些文件等。
4)CPU 相关信息:进程在让出 CPU 时,必须保存该进程在 CPU 中的各种信息,比如各种寄存器的值。用于实现进程切换,确保这个进程再次运行的时候恢复 CPU 现场,从断点处继续执行。这就是所谓的保存现场。
重点信息:
- 标识相关:PID,UID等等
- 文件相关:进程需要记录打开的文件信息,于是需要文件描述符表
- 内存相关:内存指针,指向进程的虚拟地址空间(用户空间)信息
- 优先级相关:进程相对于其他进程的调度优先级
- 上下文信息相关:CPU的所有寄存器中的值、进程的状态以及堆栈上的内容,当内核需要切换到另一个进程时,需要保存当前进程的所有状态,即保存当前进程的进程上下文,以便再次执行该进程时,能够恢复切换时的状态,继续执行。
- 状态相关:进程当前的状态,说明该进程处于什么状态
- 信号相关:进程的信号处理函数,以及记录当前进程是否还有待处理的信号
- I/O相关:记录进程与各种I/O设备之间的交互
进程内存分配
每个进程运行的时候,在32位Linux下,会分配4G的虚拟内存,用户空间3G,内核空间1G。每个进程都有各自的私有用户空间,该空间独立透明,最高地址的1GB内核空间则为所有进程以及内核所共享以用于系统内核执行一些系统调用。
操作系统怎样调度进/线程的
调度算法
- 先到先服务算法
- 短作业优先
- 时间片轮转
- 优先级
- 多级反馈队列
进程的上下文切换
引起进程切换的事件:
- 当前进程的时间片到
- 有更高优先级的进程到达
- 当前进程主动阻塞
- 当前进程终止
进程上下文切换保存的内容有:
- 页表 – 对应虚拟内存资源
- 文件描述符表/打开文件表 – 对应打开的文件资源
- 寄存器 – 对应运行时数据
- 信号控制信息/进程运行信息
为什么需要线程
由于创建或撤销进程时,系统都要为之分配或回收资源,如内存空间、I/O 设备等,需要较大的时空开销,限制了并发程度的进一步提高。为减少进程切换的开销,把进程作为资源分配单位和调度单位这两个属性分开处理,即进程还是作为资源分配的基本单位,但是不作为调度的基本单位(很少调度或切换),把调度执行与切换的责任交给线程,即线程成为独立调度的基本单位,它比进程更容易(更快)创建,也更容易撤销。简而言之,引入粒度更小的线程可以减少程序在并发执行时所付出的时间和空间开销,提高并发性能。
参考链接
线程和进程的深入解读-阿里云开发者社区 (aliyun.com)