1. 进程
通常将运行中的程序称为进程。
1.1 进程的状态及变迁
如何理解上述各状态?
- 创建状态:进程正在被创建
- 运行状态:该状态下进程占用着CPU
- 就绪状态:进程可运行,但是由于其它进程占用着当前CPU时间片处于运行状态而暂时停止运行
- 阻塞状态:等待其它时间的发生(比如I/O操作完成)而暂时停止运行
- 结束状态:简单理解为进程正在从系统中消失
- 挂起状态:操作系统通常会把处于阻塞状态的的进程的物理空间换出到磁盘,以节省物理内存。而挂起状态描述的是进程没有实际占用物理内存空间的情况。进一步又可以分为两种:就绪挂起和阻塞挂起
状态变迁
- NULL -> 创建状态:新进程被创建
- 创建状态 -> 就绪状态:当进程被创建完成并初始化后,一切就绪准备运行时,变为就绪状态,这个过程是很快的;
- 就绪态 -> 运行状态:处于就绪状态的进程被操作系统的进程调度器选中后,就分配给 CPU 正式运行该进程;
- 运行状态 -> 结束状态:当进程已经运行完成或出错时,会被操作系统作结束状态处理;
- 运行状态 -> 就绪状态:处于运行状态的进程在运行过程中,由于分配给它的运行时间片用完,操作系统会把该进程变为就绪态,接着从就绪态选中另外一个进程运行;
- 运行状态 -> 阻塞状态:当进程请求某个事件且必须等待时,例如请求 I/O 事件;
- 阻塞状态 -> 就绪状态:当进程要等待的事件完成时,它从阻塞状态变到就绪状态;
1.2 进程的控制结构
进程控制块PCB 是进程存在的唯一标识
PCB包含如下信息:进程描述信息、进程控制和管理信息、资源分配清单、CPU相关信息
- 进程描述信息
- 进程标识符:标识各个进程,每个进程都有一个并且唯一的标识符
- 用户标识符:进程归属的用户
- 进程控制和管理信息
- 进程当前状态
- 进程优先级
- 资源分配清单:有关内存地址空间或虚拟地址空间的信息,所打开文件的列表和所使用的 I/O 设备信息
- CPU相关信息:比如CPU 中各个寄存器的值
通常通过链表的方式把具有相同状态的进程链在一起,组成各种队列,如就绪队列、阻塞队列等。
1.3 进程的上下文切换
1. CPU上下文切换
简单来讲CPU上下文是CPU在运行任何任务前所必须依赖的环境,包括CPU寄存器和程序计数器。
CPU 上下文切换就是先把前一个任务的 CPU 上下文保存起来,加载新任务的上下文到这些寄存器和程序计数器,再跳转到程序计数器所指的新位置,运行新任务。
系统内核会存储保持下来的上下文信息,当此任务再次被分配给 CPU 运行时,CPU 会重新加载这些上下文,这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。
可以根据任务的不同,把 CPU 上下文切换分成:进程上下文切换、线程上下文切换和中断上下文切换。
1.2 进程上下文切换
进程是由内核调度和管理的,进程的切换只能发生在内核态。
进程的上下文切换不仅包含了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的资源。
1.3 发生进程上下文切换的场景
- 某个进程的时间片耗尽
- 发生硬件中断,转而执行内核中的中断服务程序
- 需要运行优先级更高的进程
- 通过sleep等方法将自己主动挂起
- 在系统资源不足,要等到资源满足才可以运行
- ......
2. 线程
2.1 为什么要引入线程
进程是与资源有关的,而进程又是动态的,因此进程进行切换时需要占用系统较多的开销,影响了系统的并发性能,那么有没有什么办法可以尽量的降低系统开销呢,于是引入了线程,尽量减小程序在并发执行时所付出的时空开销,提高操作系统的并发性能。
2.2 什么是线程
线程是进程当中的一条执行流程
同一个进程内的多个线程之间共享代码段、数据段、打开的文件等资源,但是每个线程拥有各自独立的寄存器和栈
2.3 线程的优缺点
优点:
- 一个进程中可以有多个线程
- 各个线程之间可以并发执行
- 各个线程之间可以共享地址空间和文件等资源
缺点:
3. 线程和进程的比较
- 进程是资源分配的单位,线程是CPU调度的单位
- 进程拥有完整的资源平台,线程只独享必不可少的资源,如寄存器和栈
- 线程能减少并发执行的时间和空间开销
为什么线程相比进程能减少开销?
- 线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们;(创建)
- 线程的终止时间比进程快,因为线程释放的资源相比进程少很多;(终止)
- 同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的;(切换)
- 同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候不需要经过内核,这就使得线程之间的数据交互效率更高;
4. 并行与并发
单核 cpu 下,线程实际还是串行执行 的。操作系统通过做任务调度器,将 cpu 的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于 cpu 在线程间(时间片很短)的切换非常快,人类感觉是同时运行的 。
一般会将这种线程轮流使用 CPU 的做法称为并发
多核 cpu下,每个 核(core) 都可以调度运行线程,这时候线程可以是并行的
5. 多进程与多线程
多进程和多线程都是可以实现同时执行多个任务的方式。
通俗的理解:在一台电脑上登录两个QQ为两个进程,在一个QQ中处理不同的会话是多线程
和多进程相比:
- 多线程是一种开销小的多任务操作方式(创建、销毁、切换等等)‘
- 线程间的通信机制更方便。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行;线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改等
- 提高应用程序响应。当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以避免这种情况。
- 使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不同的线程运行于不同的CPU上。
- 改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改。
如何选择多线程和多进程?
6. 调度
后续在补充吧。。。