操作系统体系构建——有关进程、线程与内存管理
操作系统体系构建——有关进程、线程与内存管理
问题引出
在目前中文操作系统的教材上有着这样一句话:
- “对于用户级线程系统,其调度仍是以进程为单位进行的……用户级线程的主要缺点在于:(1)系统调用的阻塞问题。在基于进程机制OS中,大多数系统调用将使进程阻塞,因此,当线程执行一个系统调用时,不仅该线程被阻塞,而且,进程内的所有线程会被阻塞。而在内核支持线程方式中,则进程中的其他线程仍然可以运行。……”
用户级线程
:在用户空间中实现的。对线程的创建、撤销、同步与通信等功能,都无需内核的支持,即用户级线程是与内核无关的
。……由于这些线程的任务控制块都是设置在用户空间,而线程所执行的操作也无需内核的帮助,因而内核完全不知道用户级线程的存在。
- “对于用户级线程系统,其调度仍是以进程为单位进行的……用户级线程的主要缺点在于:(1)系统调用的阻塞问题。在基于进程机制OS中,大多数系统调用将使进程阻塞,因此,当线程执行一个系统调用时,不仅该线程被阻塞,而且,进程内的所有线程会被阻塞。而在内核支持线程方式中,则进程中的其他线程仍然可以运行。……”
仔细阅读这两个概念,思考后,我们可以发现:
- 既然用户级线程的实现无需内核的支持,那么为什么用户级线程阻塞后,进程中的所有线程都会被阻塞呢?操作系统再调度
同一个进程下的其他线程
运行不就可以了吗? - 答案当然是
- 不行
- 既然用户级线程的实现无需内核的支持,那么为什么用户级线程阻塞后,进程中的所有线程都会被阻塞呢?操作系统再调度
首先我们需要明确的是,操作系统本质上是一个
软件
,它是开机时通过加载在磁盘中的操作系统程序来调入到内存中运行的,以Windows为例,操作系统加载完成后,才会出现我们现在使用的对用户友好的GUI(图形用户界面),从而方便地进行系统调用
- 由于操作系统产生的目的之一是“合理地组织、调度计算机的工作与资源的分配 ”
- 所以操作系统程序的代码就必然要对相关功能进行实现,如
任务调度
、中断处理
等。 - 而代码进行功能实现就必然要占用内存空间,这就形成了操作系统内核运行的地方——
内核空间
- 而与之对应的,则是用户空间
- 内核空间:操作系统
内核程序
运行的地方,用于实现中断的处理、资源的调度等,是最接近硬件
的部分,用户无法随意访问,是保证系统稳定的重要手段 - 用户空间:用户程序运行的地方,只能访问
用户地址空间
,不能直接访问系统中的软硬件资源,只能通过访管指令
申请系统调用
来进入操作系统核心态获得资源
- 内核空间:操作系统
到这里,概念会变的更加混乱,继续往下
- 我们需要深刻的认识到
- 现代操作系统是靠
中断
驱动的软件 - 而靠中断驱动,就必须要进入内核态,因为
中断会使CPU由用户态变为内核态,是操作系统内核夺回CPU使用权的唯一途径
- 为什么是CPU由用户态变为内核态呢?
- CPU中有关于操作系统的程序状态字寄存器,为0处于内核态,为1处于用户态。根据寄存器的状态才能区分操作系统应该访问哪片内存区域。
- 现代操作系统是靠
- 其实到这里,答案也就明确了
- 在
不支持内核级线程
的操作系统中内核没有为线程提供支持,线程是一个用户态
实现,用户级线程无法进入内核进行系统的调度,“其调度仍是以进程为单位进行的”- 对于这样的操作系统,线程的调度事实上是
进程行为
,线程所在的进程仅能占用一个CPU处理,一个进程仅有一个线程运行
。所谓的“线程调度”没有内核支持,无法提升权限至内核态,更无法充分利用多核特性。 - 所有的任务实际上都是以进程为单位运行,故某时刻任务陷入休眠时,自然就会导致进程休眠。
- 对于这样的操作系统,线程的调度事实上是
- 操作系统内核定义的线程之所以能在阻塞的时候调度是因为操作系统拥有
最底层的硬件概念
帮助操作系统强行夺走
程序的运行权来运行操作系统调度,这个概念就是中断
。- 利用
硬件的时钟中断
,不论当前执行权在谁手里,操作系统都有权夺走线程的执行能力,将执行权交给另一个线程,因此同一个进程中一个线程的阻塞不会影响另一个线程。也就可以支持多线程
在多处理机
上并发运行。 - 而纯粹在用户态实现的线程,并没有
硬件
能够帮助用户级的调度代码夺走用户级下正在运行中的协程代码的执行权。- 因此这非常依赖于各个线程在自己阻塞时主动让出自己的执行权,需要不同线程有协作意识,所以目前更多的被称为“协程”。
- 利用
- 在
- 捋清以上理念后,就可以解决开头提出的问题,同时也可以明晰多线程一对一模型的优点
- 每个用户线程都对应一个内核线程,所以任意一个用户线程阻塞后,对应的内核线程都可以调度一个新的线程运行
- 我们需要深刻的认识到
强行联系上内存管理的知识
- 目前操作系统采用的物理内存管理方式多为段页式管理,但是虚拟内存管理方式是采用请求分页式管理
- 疑惑产生
- 段页式优越性远大于分页式,为什么虚拟内存管理不使用段页式呢?
- 此处不能割裂的看
- 虚拟内存的根本目的是将容量不足的物理内存地址空间扩展
- 使用请求分页方式的原因套概念说就是
- 分页使用离散的地址空间分配,地址映射更加灵活
- 以页为单位大小固定,地址转化的难度低,且能很好的使用页面置换算法
- 但更应该联系物理内存的段页式管理来看
- 段页式管理:将作业中的进程按逻辑分段,每个进程对应一个段表,段表中每个段又对应着一份页表,所以
基本的分配单位是页
- 基本分配单位是页,但实际物理层面进行硬件调用时首先是
以段为单位调入内存
,但由于段长可能过大导致内存地址空间不够,且会有很多暂时用不到的数据占用内存,导致效率降低
- 段页式管理:将作业中的进程按逻辑分段,每个进程对应一个段表,段表中每个段又对应着一份页表,所以
- 此时引入虚拟内存,使用
请求分页
的技术,就可以- 虽然调入内存的是程序段,但段中
不需要使用的页
就可以不调入实际的物理空间,而是仅在虚拟地址空间中
待命,等到需要使用的时候,通过页面置换算法
来将页面从外存调入内存中
- 虽然调入内存的是程序段,但段中
- 这大概就是
请求分页
对应段页式管理
的原因 - 同时也明确了,单独存在的物理内存管理中不需要页面置换算法,如果只存在物理内存,就不会有
虚拟地址空间中的缺页中断
,更不会产生页面的对换
- 联系上内存管理的基本形态,也就从内存的角度更系统的认识了线程的调度
- 分段中目前调入内存中的某些分页,就是对应着某个线程
由于本人在中文互联网难以找到相关论述资料,以上观点仅为对408操作系统内容的大致分析、思考和猜想