目录
进程通信
什么是进程通信?
1.共享存储
2.管道通信
3.消息传递
4.客户机--服务器系统
线程的概念和特点
什么是线程,为什么要引入线程?
线程的特性和优点
引入线程机制后,有什么变化?
线程的实现方式多线程模型
线程的实现方式
用户级线程(User-Level Thread, ULT)
内核级线程(Kernel-Level Thread, KLT, 又称“内核支持的线程”)
多线程模型
一对一模型
多对一模型
多对多模型
进程通信
、
什么是进程通信?
顾名思义,进程通信就是指进程之间的信息交换。
进程是分配系统资源的单位(包括内存地址空间),因此 各进程 拥有的 内存地址空间相互独立 。
为了保证安全, 一个进程不能直接访问另一个进程的地址空间 。 但是进程之间的信息交换又是必须实现的。 为了保证进程间的安全通信,操作系统提供了一些方法。
1.共享存储
两个进程对共享空间的 访问 必须是 互斥 的(互斥访问通过操作系统提供的工具实现)。操作系统只负责提供共享空间和同步互斥工具(如P 、 V 操作)
基于数据结构 的共享:比如共享空间里只能放 一个长度为10 的数组。这种共享方式速度慢、 限制多,是一种 低级通信 方式
基于存储区 的共享:在内存中画出一块共享存储区,数据的形式、存放位置都由进程控制,而不是操作系统。相比之下,这种共享方式速度更快,是一种 高级通信 方式
2.管道通信
1. 管道只能采用 半双工通信 ,某一时间段内只能实现单向的传输。如果要实现 双向同时通信 ,则 需要设置两个管道 。
2. 各进程要 互斥 地访问管道。
3. 数据以字符流的形式写入管道,当 管道写满 时, 写进程 的 write() 系统调用将被 阻塞 ,等待读进程将数据取走。当读进程将数据全部取走后, 管道变空 ,此时 读进程 的 read() 系统调用将被 阻塞 。
4. 如果 没写满,就不允许读。 如果 没读空,就不允许写。
5. 数据一旦被读出,就从管道中被抛弃,这就意味着 读进程最多只能有一个 ,否则可能会有读错数据的情况
3.消息传递
进程间的数据交换以 格式化的消息 ( Message )为单位。进程通过操作系统提供的“发送消息 / 接收
消息”两个 原语 进行数据交换。
4.客户机--服务器系统
(了解即可)
客户机/服务器系统 Client/server system 简称C/S系统。是一类按新的应用模式运行的分布式计算机系统。现在的LAN,Internet提供的多种服务都是这种模式
线程的概念和特点
什么是线程,为什么要引入线程?
线程的特性和优点
进程间并发,开销很大 线程间并发,开销更小 引入线程机制后,并发带来的系统开销降低,系统并发性提升
注意:从属于不同进程的线程间切换,也会导致进程的切换!开销也大!
从属同一进程的各个线程共享进程拥有的资源。 进程间通信必须请求操作系统服务(CPU 要切换到核心态),开销大同进程下的线程间通信,无需操作系统干预,开销更小
注意:从属于不同进程的线程间通信,也必须请求操作系统服务!
引入线程前, 进程 既是 资源分配 的基本单位,也是 调度 的基本单位。
引入线程后, 进程是资源分配的基本单位,线程是调度的基本单位。
线程也有运行态、就绪态、阻塞态
在 多 CPU 环境下,各个线程也可以分派到不同的CPU 上 并行 地执行。
引入线程后,进程是资源分配的基本单位。而 线程几乎不拥有资源 ,只拥有极少量的资源(线程控制块TCB 、寄存器信息、堆栈等)
引入线程机制后,有什么变化?
类比:
切换进程运行环境:有一个不认识的人要用桌子,你需要你的书收走,他把自己的书放到桌上
同一进程内的线程切换 = 你的舍友要用这张书桌,可以不把桌子上的书收走
线程的实现方式多线程模型
线程的实现方式
用户级线程(User-Level Thread, ULT)
历史背景:早期的操作系统(如:早期Unix)只支持进程, 不支持线程。当时的“线程”是由线程库实现的
从代码的角度看,线程其实就是一段代码逻辑。 上述三段代码逻辑上可以看作三个“线程”。 while 循环就是一个最弱智的“线程库”,线程库完成了对线程的管理工作(如调度)。
很多编程语言提供了强大的线程库,可以实现线程的创建、销毁、调度等功能。
1. 线程的管理工作由谁来完成?
用户级线程由应用程序通过线程库实现,
所有的 线程管理工作 都由 应用程序负责 (包
括线程切换)
2. 线程切换是否需要CPU变态?
用户级线程中, 线程切换 可以在 用户态 下
即可完成,无需操作系统干预。
3. 操作系统是否能意识到用户级线程的存在?
在用户看来,是有多个线程。但是在操作系统内核看来,并意识不到线程的存在。
“ 用户级线程 ”就是“ 从用户视角看能看到的线程 ”
4. 这种线程的实现方式有什么优点和缺点?
优缺点
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞, 并发度不高 。多个线程不可在多核处理机上并行运行。
内核级线程(Kernel-Level Thread, KLT, 又称“内核支持的线程”)
大多数现代操作系统都实现了内核级线程,如Windows、 Linux
1. 线程的管理工作由谁来完成?
内核级线程的管理工作 由 操作系统内核 完成。
2. 线程切换是否需要CPU变态?
线程调度、切换等工作都由内核负责,因此 内核级线程的切换 必然需要在 核心态 下才
能完成。
3. 操作系统是否能意识到内核级线程的存在?
操作系统会为每个内核级线程建立相应的TCB ( Thread Control Block ,线程控制块),通过 TCB 对线程进行管理。 “内核级线程” 就是 “从操作系统内核视角看能看到的线程”
4. 这种线程的实现方式有什么优点和缺点?
优缺点
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
多线程模型
一对一模型
一对一 模型:一个用户级线程映射到一个内核级线程。每个用户进程有与用户级线程同数量的内核级线程。
优点:当一个线程被阻塞后,别的线程还可以继续执行,并发能力强。多线程可在多核处理机上并行执行。
缺点:一个用户进程会占用多个内核级线程,线程切换由操作系统内核完成,需要切换到核心态,因此线程管理的成本高,开销大。
多对一模型
多对一 模型:多个用户级线程映射到一个内核级线程。且一个进程只被分配一个内核级线程。
优点:用户级线程的切换在用户空间即可完成,不需要切换到核心态,线程管理的系统开销小,效率高
缺点:当一个用户级线程被阻塞后,整个进程都会被阻塞,并发度不高。多个线程不可在多核处理机上并行运行
重点重点重点:
操作系统只“看得见”内核级线程,因此只有 内核级线程才是处理机分配的单位 。
多对多模型
多对多 模型: n 用户及线程映射到 m 个内核级线程( n >= m )。每个用户进程对应 m 个内核级线程。
克服了多对一模型并发度不高的缺点(一个阻塞全体阻塞),又克服了一对一模型中一个用户进程占用太多内核级线程,开销太大的缺点。
可以这么理解:
用户级线程是“代码逻辑”的载体
内核级线程是“运行机会”的载体
内核级线程才是处理机分配的单位 。 例如:多核CPU环境下,上图左边这个进程最多能被分配两个核。
一段“代码逻辑”只有获得了“运行机会”才能被CPU执行
内核级线程中可以运行任意一个有映射关系的用户级线程代码,只有两个内核级线程中正在运行的代码逻辑都阻塞时,这个进程才会阻塞