为了进一步提高系统的效率,在20实际80年代引入了线程的概念。
如果用完成移到菜比喻进程,那么线程就是一次切菜,或者一次洗菜。
进程是一个任务,线程是进程中的子任务。
在引入线程之后,操作系统进行调度的单位变为线程,分配资源的单位是进程。
(在之前介绍进程的时候提到 “进程是操作系统进行调度和分配资源的单位”)
线程的定义:是进程中的一个可执行实体,是处理机调度的基本单位
线程中组成和传统的进程非常类似:有唯一标识符,有用于保存CPU运行现场的数据结构,等等。一个进程的存储空间中保存代码段,数据段,以及属于这个进程的若干个线程
线程和进程的对比
-
拥有的资源
- 操作系统是以进程为单位分配资源的,一个进程下的多个线程可以该共享进程的资源,线程可以拥有的资源是比较少的
- 进程拥有独立的地址空间,用来存放代码段和数据段。每个进程拥有打开的文件(),拥有至少一个线程。
-
调度
- 进程的调度的花销比较大,需进行进程上下文(理解为进程运行的时候需要的环境就好)的切换
- 在同一个进程内不同线程的切换开销比较小,仅把线程拥有的一小部分资源变换了即可
假设切菜是一个进程,洗菜是一个进程,从切黄瓜到切萝卜(线程切换)只需要换“菜”就好;从洗菜到切菜(进程调度),还需要从砧板走到水槽换一个环境。
-
并发性
引入线程后,使得系统的并发执行程度更高。 进程之间、进程内的多线程之间可并发执行。
-
安全性
- 多进程实现的安全性更好
同一进程的多线程共享进程的所有资源,一个错误的线程可以任意改变另一个线程使用的数据而导致错误发生,但是系统绝不允许一个进程有意或无意破坏另一进程,所以使用多线程实现在安全性上会更好
但是使用多线程实现会更方便资源共享
- 多进程实现的安全性更好
操作系统对线程的支持
用户级线程
如,POSIX 的 Pthread 线程库
- 有关线程的调度工作有用户进程自己完成。这要求用户进程需要自己设计进程调度算法
- 内核以进程为单位进行调度。一个线程阻塞,其依附的进程也阻塞。
内核级线程
- 有关线程的管理工作都由内核完成。应用程序通过系统调用来创建或撤销线程。
- 一个线程的阻塞,不影响其他线程的执行
如,Windows、Linux、多处理机系统
两级组合
- 既支持用户级线程,也支持核心级线程
- 用户级多个线程对应核心级多个线程
- 当内核了解到一个线程阻塞后,通知运行时系统,重新调度其他线程
(这一部分需要详细了解的同学建议去看书《操作系统原理教程》)
如Solaris
感觉挺奇怪的一种方式,一个进程申请多个LWP(轻进程),把LWP看作虚拟CPU(或者可以说是一个代理)。一个LWP对应一个内核级的线程,一个LWP上可以交替运行一个进程的不同线程