深入理解内核态和用户态

1. 内核态和用户态、内核线程和用户线程等解释

操作系统调度CPU的最小单元是线程,也叫轻量级进程(Light Weight Process),在一个进程里可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量。处理器在这些线程上高速切换,让使用者感觉到这些线程在同时执行。

系统的用户空间和内核空间:

虚拟内存被操作系统划分成两块:内核空间和用户空间,内核空间是内核代码运行的地方,用户空间是用户程序代码运行的地方。当进程运行在内核空间时就处于**内核态**,当进程运行在用户空间时就处于**用户态**,为了安全,它们是隔离的,即使用户的程序崩溃了,内核也不受影响。说起这个概念就是因为线程上下文切换的概念。虽然线程上下文切换比进程切换成本要低但是,线程切换也是很影响性能的。线程上下文切换就涉及用户态到内核态的转换。

线程的实现可以分为两类:

- 1、用户级线程(User-Level Thread)

- 2、内核线线程(Kernel-Level Thread);而java线程就是内核级线程。

1.1 用户线程(User-Level Thread)

不需要内核支持而在用户程序中实现的线程,其不依赖于操作系统核心,应用进程利用线程库提供创建、同步、调度和管理线程的函数来控制用户线程。不需要用户态/核心态切换,速度快,操作系统内核不知道多线程的存在,因此一个线程阻塞将使得整个进程(包括它的所有线程)阻塞。由于这里的处理器时间片分配是以进程为基本单位,所以每个线程执行的时间相对减少。

优点:

- 线程的调度不需要内核直接参与,控制简单。

- 可以在不支持线程的操作系统中实现。

- 创建和销毁线程、线程切换代价等线程管理的代价比内核线程少得多。

- 允许每个进程定制自己的调度算法,线程管理比较灵活。

- 线程能够利用的表空间和堆栈空间比内核级线程多。

- 同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起。另外,页面失效也会产生同样的问题。

缺点:

- 资源调度按照进程进行,多个处理机下,同一个进程中的线程只能在同一个处理机下分时复用。

1.2 内核线程(Kernel-Level Thread)

由操作系统内核创建和撤销。内核维护进程及线程的上下文信息以及线程切换。一个内核线程由于I/O操作而阻塞,不会影响其它线程的运行。

优点:当有多个处理机时候,一个进程的多线程可以同时执行。

缺点:由内核进行调度。

混合线程

混合线程是内核级别线程和用户级别线程的混合体,提供了以上两种模型的优点,但是带来很大的复杂性。

1.3 ULT和KLT之间的关系

ULT和KLT区别:

程序执⾏的时候实际上分为两种状态,这个状态会被⼀条线划分,上⾯称之为⽤户态,下⾯称之为系统/内核态。⽤户态执⾏的都是我们⾃⼰写的代码,⽐如我们做的登录、⽤户CPU时间⽚分配⽅式。但是这些都是由操作系统做⽀持的,操作系统⽀持的时候就得进⼊系统态。举个例⼦调⽤⽂件读写操作,实际上是调⽤类似 open 的 API,这个API最终是由操作系统实现的,操作系统实际上会把API翻译成具体的系统调⽤ syscall,然后在操作系统⾥⾯执⾏⼀些代码,所以说这个代码实际上分为⽤户态代码和系统

态代码。当从⽤户态代码进⼊系统态代码调⽤的时候会涉及到上下⽂切换,这是要付出⼀定的代价的。很显然系统线程去创建去调度是要付出这些代价的,所以很多时候系统线程成本会⾮常的⾼,当我们频繁的去创建系统线程销掉系统线程这种代价实在太⼤了。

1.4 java线程

java线程生命周期:

休眠状态(BLOCKED、WAITING、TIMED_WAITING)与RUNNING状态的转换

1、RUNNING状态与BLOCKED状态的转换

线程等待 synchronized 的隐式锁,RUNNING —> BLOCKED

线程获得 synchronized 的隐式锁,BLOCKED —> RUNNING

2、RUNNING状态与WAITING状态的转换

获得 synchronized 隐式锁的线程,调用无参数的Object.wait()方法

调用无参数Thread.join()方法

调用LockSupport.park()方法,线程阻塞切换到WAITING状态,

调用LockSupport.unpark()方法,可唤醒线程,从WAITING状态切换到RUNNING状态

3、RUNNING状态与TIMED_WAITING状态的转换

调用带超时参数的 Thread..sleep(long millis)方法

获得 synchronized 隐式锁的线程,调用带超时参数的Object.wait(long timeout)方法

调用带超时参数的Thread.join(long millis)方法

调用带超时参数的LockSupport.parkNanos(Object blocker,long deadline)方法

调用带超时参数的LockSupport.parkUntil(long deadline)方法

1.5 线程上下文切换

线程上下文切换过程:

程序计数器的作用:

程序计数器是一块较小的内存空间,它可以看作是当前线程所执行字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。且由于java虚拟机的多线程是通过线程轮流切换并分配器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器是一个内核)都只会执行一条线程中的指令,因为为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,我们称这类区域为“线程私有”的内存。

线程切换时需要知道在这之前当前线程已经执行到哪条指令了,所以需要记录程序计数器的值,另外比如说线程正在进行某个计算的时候被挂起了,那么下次继续执行的时候需要知道之前挂起时变量的值时多少,因此需要记录CPU寄存器的状态。所以一般来说,线程上下文切换过程中会记录程序计数器、CPU寄存器状态等数据。

1.6 CPU状态之间的转换:

用户态--->内核态:唯一途径是通过中断、异常、陷入机制(访管指令)

内核态--->用户态:设置程序状态字PSW

以下三种情况会导致用户态到内核态的切换:

- 1)系统调用

这是用户态进程主动要求切换到内核态的一种方式,用户态进程通过系统调用申请使用操作系统提供的服务程序完成工作。比如前例中fork()实际上就是执行了一个创建新进程的系统调用。

而系统调用的机制其核心还是使用了操作系统为用户特别开放的一个中断来实现,例如Linux的int 80h中断。

- 2)异常

当CPU在执行运行在用户态下的程序时,发生了某些事先不可知的异常,这时会触发由当前运行进程切换到处理此异常的内核相关程序中,也就转到了内核态,比如缺页异常。

- 3)外围设备的中断

当外围设备完成用户请求的操作后,会向CPU发出相应的中断信号,这时CPU会暂停执行下一条即将要执行的指令转而去执行与中断信号对应的处理程序,

如果先前执行的指令是用户态下的程序,那么这个转换的过程自然也就发生了由用户态到内核态的切换。比如硬盘读写操作完成,系统会切换到硬盘读写的中断处理程序中执行后续操作等。

这3种方式是系统在运行时由用户态转到内核态的最主要方式,其中系统调用可以认为是用户进程主动发起的,异常和外围设备中断则是被动的。

2. cpu上下文切换

Linux 是个多用户系统,支持大于cpu核数的任务在系统上运行所以不可避免的出现cpu资源竞争,竞争CPU会导致 上下文切换

CPU上下文切换:

CPU在不同的任务之前切换需要保存任务的运行资源记录:CPU得知道从哪里去加载任务,又从哪里开始运行所以需要用到CPU寄存器和程序计数器。在理解上面的基础上CPU上下文切换就是保存上一个任务运行的寄存器和计数器信息切换到加载下一个任务的寄存器和计数器的过程

cpu上下文切换分类:

- 进程上下文切换

- 线程上下文切换

- 中断上下文切换

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270