c++应用网络编程之三用户态和内核态

一、基本介绍

计算机初始是没有什么用户空间内核空间之说的。这两个是从有了OS之后才出现的。这两个概念本来属于操作系统的相关概念,为什么拿到网络编程之中进行介绍呢?最主要的原因在于,网络编程是少有几个在开发者中经常遇到用户态和内核态显示交互的场景。
那么为什么会有用户空间和内核空间的划分呢?也很简单。首先弄明白一件事,编程的主要目的是什么?是通过控制计算机的CPU来处理各种IO或相关操作来达到某种需求。而实际情况是,不管是CPU还是各种硬件或者IO操作等,其具有相当的专业性和复杂性,这就无形中为编程处理立起了一道无形墙。其次,各种操作间的协调处理也是一个很大的麻烦。所以就发展出来操作系统。操作系统负责屏蔽了各种硬件操作的不同和复杂性,提供了统一的入口,并协调各种硬件及IO的行为。举一个简单的例子,在Linux上,基本上所有的硬件都可以用文件句柄来统一表示,并统一为读、写等操作。
同样,在计算机的应用中,往往还有一种类似于门禁的使用控制需求,即不能是所有的程序都可以操作一些硬件或者具体的某些动作,这都是OS出现的目的所有。当然,还有其它不少的场景都是OS出现的一种必然。
这是不是类似于计算机专业中的啥玩意儿都可以增加一层来解决的设计思想。

二、用户空间和内核空间

用户空间和内核空间,简单理解就是使用操作系统应用的开发者工作的空间;内核空间就是操作系统自己工作的空间。但这么定义其实是很模糊的,因为根本不知道怎么界定两个空间。其实所谓空间在计算机世界中就是地址,在操作系统中,把一部分内存地址(虚拟地址)定义为内核空间,另外一部分定义为用户空间。在32位的Linux操作系统中,其虚拟的内存寻址空间为4G,一般把最高的1G长度的空间即0xc00000000xffffffff定义为内核空间地址,把0x000000000xbfffffff的空间地址定义为用户空间地址。
这是从空间形态来划分,还可以从指令集的操作权限划分为用户态和内核态,即CPU的指令操作划分成几个等级,比如常见的Intel的CPU划分为Ring0~Ring3四个等级(但在OS中一般使用了0和3两个状态)。那么当程序运行在Ring0时为内核态,Ring3时为用户态。用户态只能操作用户地址空间,反之亦然。如果搞错访问地址,轻则程序崩溃重则系统崩溃。
这样的区分,使得即使是小白操作硬件时产生的问题,都会被操作系统屏蔽和保护,不至于产生整体的宕机。毕竟,现代计算机已经不是早期的只执行两个程序,可能一台服务器上运行着成百上千个服务呢。
从而就可以明白操作系统之所以设计出两种形态的本质目的就是隔离变化、降低风险提高系统的安全性和稳定性。
用户空间比较容易理解,这里再简单说明一下内核态,内核态的虚拟地址有四种映射方式:
1、直接映射区
即虚拟内存地址和物理内存地址是显示一一映射的,即从0xc0000000+896M,线性一一对应。
2、动态内存映射区
这块地址是用内核的内存分配函数vmalloc来控制。此处的特点就是在OS中学习的,虚拟地址是线性的,但物理地址未必。
3、永久内存映射区
即内核中专门开辟的一段线性地址,供映射高端内存。通常情况下这个比较小,在早期的Linux内核中有大约4M的空间。
4、固定内存映射区
内核中在顶端预留的一块线性空间地址,用于特殊需求,比如高端内存的临时映射等等。

三、二者的交互

有了内核空间和用户空间,就有了数据交换的需求。既然修建了城墙,必然会有墙内外的各种往来。人类可以通过城门,检查各种来往沟通的情况。二者的交互,最简单的当然是使用接口(函数)。那么什么情况下会发生二者的切换呢?
1、系统调用
2、异常
3、中断
一般在实际的开发中,上层应用开发者,也就是用户空间开发者,应用的最多的就是系统调用。中断一般是比较贴近硬件的比较多。而异常一般不属于讨论的范畴。为什么要讨论二者交互或者切换呢?最主要是,在网络编程中,瓶颈在哪里要搞清楚,弄明白。看一个基本的二者交互的流程:
1、用户程序发起系统调用,系统保存当前Context、堆栈信息等
2、复制用户态参数进入内核空间,切换进入内核态
3、检查相关安全机制是否符合条件
4、执行内核态中的代码
5、复制执行的内核态结果到用户空间,切换用户态
6、恢复用户态Context等并处理结果
7、用户程序继续执行
上面说的比较简单,比如数据如何进行内核与用户空间二者间的复制,状态如何保存等等,都是相当复杂的。当然也有不走寻常路的,比如人还可以偷偷翻跃城墙,道理是一样的。这是另外一个话题,这里不做展开。
看到这些,就明白了,为什么现在的DPDK等新技术,都by pass通过,这就是看到瓶颈绕开瓶颈的解决方式。

四、总结

任何技术都有它的局限性,随着时间的发展,这种局限性可能愈发的明显。这给开发者一个警示,要与时俱进,不能坐在原地吃老本儿。学如逆水舟,不进则退。以前不太明白这句话的意思,现在理解已经非常深刻了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值