操作系统深入学习-----用户态内核态、多线程模型、线程映射

一.概念介绍


什么是内核,什么是操作系统,二者区别是什么

1.操作系统
操作系统(Operating System,简称OS)是管理计算机硬件与软件资源的计算机程序。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入设备与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面

  • 从计算机用户的角度来说,计算机操作系统体现为其提供的各项服务;从程序员的角度来说,其主要是指用户登录的界面或者接口
  • 实际上,操作系统(OS)就是运行在我们计算机上的一个程序,它为用户提供了操作和使用计算机能力的接口和交互界面,本身不具备底层能力。

2.内核
内核,是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最基本的功能,是操作系统工作的基础,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。

现代操作系统设计中,为减少系统本身的开销,往往将一些与硬件紧密相关的(如中断处理程序、设备驱动程序等)、基本的、公共的、运行频率较高的模块(如时钟管理、进程调度等)以及关键性数据结构独立开来,使之常驻内存,并对他们进行保护。通常把这一部分称之为操作系统的内核
在这里插入图片描述
p.s. 我们使用的mac book内核和linux内核并不相同,虽然他们都是从unix发展过来的,文章:mac和linux内核区别


3.总结:

  • 内核,是一个操作系统的核心。是基于硬件的第一层软件扩充,提供操作系统的最基本的功能,是操作系统工作的基础,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。
  • 操作系统一般包括内核、驱动程序、接口库、外围等组成部分,内核也只是其中一个重要的组成部分。
  • 操作系统面向用户,而内核提供了操作系统核心的进程管理,文件管理,网络等能力
用户态和内核态,用户级线程和内核级线程

用户态和内核态,也称为用户模式和内核模式。处于内核态的操作系统内核对于硬件有不受限制的使用权限,并且可以执行任何 CPU 指令以及访问任意的内存地址。
而用户态进程没有能力直接操作硬件,也没有能力访问任意的内存地址空间。用户态进程只能通过操作系统内核提供的系统调用受限地使用硬件资源。并且用户态进程不能执行一些 CPU 特权指令。用户态进程不能随意的访问内存空间或者对进程、线程进行管理,为了使应用程序访问到内核管理的资源例如CPU,内存,I/O。内核必须提供一组通用的访问接口,这些接口就叫系统调用。


  • 问题1.计算机如何知道当前处于什么模式
    保护模式下CS寄存器的低两位决定了当前CPU的特权等级
    在这里插入图片描述

  • 问题2.系统调用例子,C语言能否直接操纵?
    打一个比方:C库接口malloc申请动态内存,malloc的实现内部最终还是会调用brk()或者mmap()系统调用来分配内存。

  • 问题3.除了系统调用还有其他方式会从用户态切换到内核态吗?
    1.异常事件: 当CPU正在执行运行在用户态的程序时,突然发生某些预先不可知的异常事件,这个时候就会触发从当前用户态执行的进程转向内核态执行相关的异常事件,典型的如缺页异常。
    2.外围设备的中断:当外围设备完成用户的请求操作后,会像CPU发出中断信号,此时,CPU就会暂停执行下一条即将要执行的指令,转而去执行中断信号对应的处理程序,如果先前执行的指令是在用户态下,则自然就发生从用户态到内核态的转换。

二.操作系统层面的多线程模型,如何映射?

在特定实现中(需要利用内核态的功能),必须使用以下策略之一将用户线程映射到内核线程。一般来说分为三种:多对一,一对一,多对多。

1.多对一

在多对一模型中,许多用户级线程都映射到单个内核线程。线程管理由用户空间中的线程库处理,这非常有效。但是,如果进行了阻塞系统调用,那么即使其他用户线程能够继续,整个进程也会阻塞。由于单个内核线程只能在单个CPU上运行,因此多对一模型不允许在多个CPU之间拆分单个程。
Solaris和GNU可移植线程的绿色线程在过去实现了多对一模型,但现在很少有系统继续这样做。

在这里插入图片描述

2.一对一

一对一模型创建一个单独的内核线程来处理每个用户线程。一对一模型克服了上面列出的问题,涉及阻止系统调用和跨多个CPU分离进程。但是,管理一对一模型的开销更大,涉及更多开销和减慢系统速度。此模型的大多数实现都限制了可以创建的线程数(比如Linux就限制最大线程数为1024)。

Windows(从Win95开始)和Linux都实现了线程的一对一模型。

在这里插入图片描述

3.多对多

多对多模型将任意数量的用户线程复用到相同或更少数量的内核线程上,结合了一对一和多对一模型的最佳特性。用户对创建的线程数没有限制。阻止内核系统调用不会阻止整个进程。进程可以分布在多个处理器上。

在这里插入图片描述

三.JVM线程和内核线程关系,如何映射?

Java中的线程本质:

Java线程在JDK1.2之前,是基于称为“绿色线程”(Green Threads)的用户线程实现的,而在JDK1.2中,线程模型替换为基于操作系统原生线程模型来实现。因此,在目前的JDK版本中,操作系统支持怎样的线程模型,在很大程度上决定了Java虚拟机的线程是怎样映射的,这点在不同的平台上没有办法达成一致,虚拟机规范中也并未限定Java线程需要使用哪种线程模型来实现。线程模型只对线程的并发规模和操作成本产生影响,对Java程序的编码和运行过程来说,这些差异都是透明的。

JDK1.2之前,程序员们为JVM开发了自己的一个线程调度内核,而到操作系统层面就是用户空间内的线程实现。 而到了JDK1.2及以后,JVM选择了更加稳健且方便使用的操作系统原生的线程模型,通过系统调用,将程序的线程交给了操作系统内核进行调度

对于Sun JDK来说,它的Windows版与Linux版都是使用一对一的线程模型实现的,一条Java线程就映射到一条轻量级进程之中,因为Windows和Linux系统提供的线程模型就是一对一的。

总结:现在的Java中线程的本质,其实就是操作系统中的线程,Linux下是基于pthread库实现的轻量级进程,Windows下是原生的系统Win32 API提供系统调用从而实现多线程。

JVM线程如何映射

Java线程在Windows及Linux平台上的实现方式,如今看来,是内核线程的实现方式。这样的方式实现的线程,是直接由操作系统内核支持的——由内核完成线程切换,内核通过操纵调度器(Thread Scheduler)实现线程调度,并将线程任务反映到各个处理器上。内核线程是内核的一个分身。程序一般不直接使用该内核线程,而是使用其高级接口,即轻量级进程(LWP)。也即线程。

在这里插入图片描述

  • (说明:KLT即内核线程Kernel Thread,是“内核分身”。每一个KLT对应到进程P中的某一个轻量级进程LWP(也即线程),期间要经过用户态、内核态的切换,并在Thread Scheduler 下反应到处理器CPU上。)
证明Java线程既不是用户级也不是内核级

出处:证明来自这篇文章下方评论

  1. 证明java线程不是纯粹用户级线程:java中有个fork join框架,这个框架是利用多处理技术进行maprudce的工作,也就证明了内核是可以感知到用户线程的存在,因此才会将多个线程调度到多个处理器中。还有,java应用程序中的某个线程阻塞,是不会引起整个进程的阻塞,从这两点看,java线程绝不是纯粹的用户级线程。

  2. 再来,证明java线程不是纯粹内核级线程:这点比较直观,如果使用纯粹的内核级线程,那么有关线程的所有管理工作都是内核完成的,用户程序中没有管理线程的代码。显然,java线程库提供了大量的线程管理机制,因此java线程绝不是纯粹的内核级线程。 综上,java线程是混合型的线程模型,一般而言是通过lwp将用户级线程映射到内核线程中


四.总结

  1. 内核&操作系统介绍和对比
  2. 用户态&内核态,用户线程&内核线程概念解释
  3. 什么是系统调用
  4. JVM线程模型,常见的采用的是一对一(内核级),但绝不是纯粹内核级的
  5. JVM线程通过调度器来实现线程调度
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值