当前位置:C++技术网 > 精选软件 > Windows核心编程入门:3 操作系统内核有哪些类型以及特色

Windows核心编程入门:3 操作系统内核有哪些类型以及特色

更新时间:2016-04-10 23:59:04浏览次数:1+次

    在文章《Windows核心编程入门1:什么是操作系统内核》中,我很详细的讲述了一下什么是操作系统内核。有了这个基础,我在来深入了解一下操作系统内核有哪几类,以及操作系统内核几种类型的设计原理和相互之间的差异。学习这些,可以促进我们对操作系统的理解。
    操作系统内核类型现在大概分为四种:单内核、微内核、混合内核(双内核)、外内核。我们下面来一个个逐步探讨。请注意我们探讨并不是以知识点方式探讨,而是以设计思想的变化形式来探讨,为什么有这么几个类型,为什么这么设计,这些类型的好坏等等。如果从思想上去感受不同的类型设计,学起来又轻松,有好理解。不必去记忆这几种类型,而是要理解这几种类型的背后思想,理解为什么这几个类型是这么一个名称。

1.单内核模式
    这里的内核的单个不是CPU的单核双核的意思。这个单内核表示的意思是,整个内核是一个进程。这一个进程就是内核进程,其他进程都不是内核进程。仅此一个内核进程哦。而且,这个进程内部,包含了所有内核基本功能模块,如内存管理,文件管理,进程线程管理等。
    那么这个内核进程无疑是系统最重要的进程了。如果这个进程挂了,可想而知,系统就崩溃了。我们平时看到Windows中一个进程出Bug崩溃了,这个进程就Over了。怎么办,关闭这个进程,然后重新启动这个进程呗。是的,对于普通进程来说,这个没有什么。然而对于系统进程来说,一旦内核进程出现了Bug,然后导致进程无法运行下去而崩溃了,这就表示系统崩溃了。就算你其他用户的普通进程还有很多数据没有处理,或者转账正在进行,系统也说挂就挂了,没得商量。然后,数据就消失了,损失就这么造成了。如果你对损失不清楚,那么举个例子来说。如果在进行转账,将A的1亿转给B,如果先扣掉A的钱,然后加B的钱,这样正常情况下,就完成了。然而内核进程在扣掉A钱之后,准备给B加钱的时候突然崩溃了。因为是系统内核进程,本来内核进程就是最大的Boss了,他要死了,谁还能做什么,然后突然天塌下来了。B没有收到钱,A的钱没有了,此时银行是没有很伤心,然而A就急死了。如果有记录,一切好说,如果没有记录,银行肯定不认账,银行就此获益1亿,A就完了。换一个做法,如果先给B加钱,然后再扣A的钱,加完钱后,内核进程崩溃了,结果B多了1亿,A没有扣掉,这样银行白白多支出1亿,银行肯定无论如何也要追回这个钱的。而且如果用户不退回去就是犯罪哦。哈哈哈,这是现实世界天朝发生过的案例哦。当然不是说系统崩溃,是说钱的问题。不管怎么样,都是系统出的问题。
    好了,到这里我想你大概了解了单内核的概念了吧。是不是看起来很危险呀,嘿嘿,确实很危险。所以,单内核操作系统要求系统开发人员非常可靠,必须保证系统内核的稳定。如果内核写的不好,而且这样的单内核系统,只要出bug,系统就崩溃了。即使是一些模块有问题,也会导致整个系统崩溃。这要是在工业系统、医疗系统,往往会出现大事故,搞不好爆炸,人命关天哦。所以这样的系统不适合在这些领域使用,就是因为这个特点。风险太大,谁又能够保证系统从不出错呢?
    那么单内核内部又是如何设计和运作的呢?为什么要设计这样的单内核操作系统呢?如果只有缺点,没有优点,这样的模式自然也就会被抛弃。所以,我们来看看他的优点。这个就要看看单内核内部的设计结构了。
    单内核就好比我们自己写的一个函数,在函数内用很多代码写了一个复杂的功能。比如,用switch判断,一种情况做一个处理,而且处理代码还在这个case下面写的。下面看看伪代码:
void kernel()
{
  while(1)
  {
    switch(type)
    {
        case 0:
            //所有内存相关的操作
            break;
        case 1:
            //所有文件相关的操作
            break;
        case 2:
            //所有进程线程相关的操作
            break;
        //其他case情况
    }
  }
}

    你可以把kernel函数当做内核进程的主函数,然后内核启动之后,不停的处理各种操作。这是一个模型,并不是真实的模拟。这个代码只是演示单内核的所有模块在一个进程中,而且可以相互用函数调用方式操作。更贴切点,可以理解为多个类,在同一个进程中,可以相互调用。
    你可以用C语言的模块思想来理解,将一个功能模块封装在一个函数里,多个函数就形成了多个模块,模块直接可以直接用函数调用即可。因为在同一个进程中,不用与其他进程打交道,内核内部的模块之间就是一家人,所以访问操作都是很直接的,所以这样执行的速度非常快,因此效率非常高。
    这也是单内核操作系统受欢迎的地方。只是不要将这类系统用在不能承担巨大损失的场合,一次损失也不行的。因为工业医疗这类,一次错误损失惨重。不过这类系统,还是可以用在很多场合的。而且,编写内核的人也可以写的很好。基本上是有保证的。不合适就不要勉强,也不能因为单内核系统的缺点而完全贬低他,毕竟他还有优点。
    然而,单内核的所有基本模块都在一个进程中,这样写代码和内核扩展性变得不好。单内核的映像文件也只有一个。不过这都不是事,可以通过在运行时动态加载模块运行。而且,可以将不同的模块分给不同的人来开发,都以模块形式加载到内核进程执行。在Windows中,典型的模块方式就是dll。这样既可满足扩展性,也可以让开发变得容易。这样可以将一个二进制的内核映像文件拆成多个模块文件,最后加载到内核进程中。
    同时,因为单内核是一个整体的设计思路,所以在一个进程中,模块之间相互调用简单方便,不需要很多机制。所以在设计上就非常容易设计。所以这也让单内核设计开发比其他内核开发容易的多。反正,有利就有弊。都在一块了,方便开发,方便互操作,然而却容易一次性全军覆没。而如果不在一起,沟通比较困难。等会仔细看看微内核的结构,再比较。
    那么单内核的设计思想简单粗暴,需要的模块都在一个进程中,既有优点也有缺点,我们可以将优点发挥,避开缺点就好。

2.微内核模式
    有了单内核的分析,我再来看微内核。什么是微内核呢?单内核将必要的基础功能都集中在一个进程中的。这个有风险,无法保证系统的稳定性和健壮性。所以,微内核可以解决这个问题。
    单内核可以一锅端,所以风险极大。即使写的人再高,也有可能有出错的时候。谁也无法保证。很多情况是不能容忍一次错误,就不能用单内核系统。加入系统开启发射核弹,然后敌人妥协了,然后要取消核弹发射。结果系统崩溃了,一下子无法取消了。等重启了系统,核弹已经发出去了。这样麻烦就大了去了。这样怪罪下来,这个系统的人,绝对要拿去枪毙了。或者,敌人还不咬咬切齿反攻,这个Bug岂不是代价最大的Bug了。
    微内核模式克服了单内核的这个缺点,就采用了多进程多线程方式。这样的话,一个微内核有好多个进程线程,每一个内核进程都是独立运行的,相互不依赖,相互不影响。这样一个内核进程崩溃,重启这个进程即可,系统还是正常运行。而且,不可能同时所有的内核进程都出bug崩溃的。这样无疑大大提高了系统的稳定性。
    在Windows系统中,你可能经常遇到资源管理器崩溃,然后导致打开的文件夹和文件都关掉了。然而这个并不会导致系统死掉。系统自动让资源管理器重新启动就可以了。虽然可能造成一些损失,但是还是可以接受的。
    微内核可以将基础而重要的模块放在内核中运行,把一些不太重要的放在用户态中运行。这样可以让内核变得更小。内核小了,自然系统常驻在内存的空间也就小了。用户用到用户态的功能时候,才启动那些功能,才加载到内存。这样系统运行速度也快了,硬件配置也就低了。
    不过,因为多进程分散了内核模块,这样内核模块之间的通信就变得麻烦,内核模块之间就必须使用进程间通信来沟通。单内核的时候,大家都在一个房间里聊天,微内核的时候,大家都有一个单独的房间了,更加安全,不会相互干扰了,然而想相互聊聊天,却被墙隔开了。进程之间有进程边界阻拦,就和墙是一个道理。那么不同房间的人可以通过打电话,聊QQ的方式相互沟通,然后这些需要成本呀,话费、电话设备,聊天沟通的效率就很低了,当年抬头就可以说话,现在还得用沟通设备沟通,如果网络不好的时候,更是难受。
    也正是这个原因,所以内核模块在相互沟通,协作完成功能的时候,在沟通上花费很多成本,所以导致执行效率变得低了。不过,也不是说绝对的低效率。因为这样的设计,会导致效率低下,但是如果处理的好,让沟通更容易了,效率也就提高了。
    不过你可以看到,因为微内核将多个模块分开了,自然还可以将一些不重要不常用的模块放在用户模块,用的时候才加载到内存,不用的时候就可以睡觉。这样可以定制内核的大小。这样可以做一个非常精简的内核。所以,你听说的很多内核可以增减模块,设备要求很低,就可以将很多不必要,用的不多的移除内核,然后需要的时候加载,不需要的时候也不占内存。
    那么微内核关键部分提供对硬件的抽象,其他很多的都可以让用户态的程序来做。通常叫做用户态服务器,其实就是一个用户态的程序,只是这个程序作为提供服务的程序而存在。微内核在嵌入式应用很广泛,如机器人、手机等。

3.混合内核模式(双内核)
    混合内核则是单内核与微内核的综合,更多的算是微内核的范畴。正是因为微内核大多的功能被放在了用户态服务器程序中,内核是小了,内核运行速度快了,然而很多常用模块却在用户态的服务器程序中,这些程序也要操作硬件,然后要转入内核态执行,比如文件操作。最终还是要操作IO硬件的,并且对于用户来说,这个功能时很频繁使用的,所以要经常切换到内核态再执行,这样也就导致了速度变慢。只要是在内核态的,都需要在内存中常驻。精简内核之后,用户的需求没有精简掉,所以很多放在用户态的内核代码还会经常切回到内核态执行,所以导致效率很低。
    为了解决这个问题,就是混合内核模式的发挥了。混合内核就是将这些运行在用户态的内核代码放回内核,即使不是最基本的内核模块,但是经常会用到,所以放在内核中,虽然占内存会大点,但是却让执行速度提高了,用户体验就好了。微软的Windows操作系统内核就是混合内核模式。为什么说Windows系统越高级后要求的配置越高了,因为内核越来越大了,很多重要的功能都放在内核中,系统一启动,就占据了很大的内存了。如果配置低了,内核就跑不起来,系统就运行不好了。
    混合内核更多偏重于业务,偏重于用户体验。你要知道,Windows的界面是系统的核心,而界面支持要耗费很多内核内存,这也是Linux不愿意支持界面的原因。Linux优先保证系统的高效运作,不太管你的业务需要,不太管你的用户体验。所以核心只支持字符命令,这样除掉了一个界面元素,内核不知道精简多少。不过Linux支持界面插件,选择性使用,不用界面的时候,跑的很好,用界面的时候,也是很费内存的,所以一般在服务器上,更偏向于用Linux,因为不要界面,节省内存哦。
    如果你深入了解内核的几种模式,你也就能明白Windows为什么臃肿,还不是为了用户体验。有舍才有得,这有什么好贬低的呢。操作系统为的是让我们更好的操作硬件,而不是当做一个纯粹的艺术品欣赏的。所以,Windows的优势就在于做好了用户体验,也符合人类的需求。简单好用可视化,就是最大的特色,所以Windows就流行了。
    如今的火热的安卓系统,不还是以界面作为重要的支持,如果哪个手机没有界面,只有输入命令操作,几个人用呢?安卓手机就好像是Windows的移动版。根本需求就是可视化简单的操作。

4.外内核模式
    最后一种就是外内核。这种内核模式,现在只是在研究实验阶段。并没有成熟的系统,不过我们可以学习一下,可以加深我们对系统内核的理解。
    操作系统内核是包装硬件,给上层提供操作硬件的支持。不过有时候,有些场合并不完全需要这样的效果。所以,也就有了另外一种模式。所以,不同的模式,也都是需求催生的,而不是拍脑袋想出来的。如果一个设计没有需求,也没有潜在的需求,谁去做呢,想想就可以了。
    前面几种都是包装硬件,给硬件抽象,让上层不直接操作硬件,让开发更加轻松。然而,有的场合需要应用直接操作硬件。怎么办呢?现有的系统明显不能满足,就连设计原则都违背,如何支持?
    所以就出现了外内核模式。简单来说,系统内核不抽象硬件,而是简单的管理硬件。它只管系统的保护和资源的复用。然后将硬件暴露给上层程序,这样的话,上层可以直接操作硬件哦。也就是说,我们的应用程序在外内核系统上,可以直接操作硬件哦。外内核可以让应用程序可以直接请求一个物理内存空间,或者一个磁盘扇区,然后直接对物理设备进行读写操作。系统只保证请求的硬件资源是可用的,就可以让你操作。在内核中,基本是真空的,没有任何限制。
    然而用户程序如果真的直接操作物理硬件,那不是编程很困难。当然,内核是不包装的,然而却可以在用户态提供一个运行库支持,让你更好更方便的操作硬件,也就是帮助你快速操作硬件。
    如此一来,我们要操作硬件,就不是依赖系统内核了,而是用户态的运行库了。用户态也就是内核之外了,这个运行库就好比一个内核,实际又不运行在内核,所以叫做外内核。这样的模式,给应用程序提供了直接操作硬件的机会。

    同时,内核外的运行库,可以让其他各种操作系统运行,运行库可以选择调用不同的操作系统。或者说,同时可以运行多个操作系统,然后这些操作系统通过外核上的运行库来操作硬件。这就好比,外内核只是简单的包装一下,然后可以支持多个操作系统运行,也可以支持应用程序直接操作硬件哦。想想还是挺激动的。

    最后,至于几种内核的比较,在每一种内核模式的讲解中,都基本说的很清楚了,就不重复说了。