聊了聊宏内核和微内核,并吹了一波 Linux
内核是操作系统非常重要的组成部分,同时也是操作系统的核心。内核管理着系统资源,内核向上连接着应用程序,向下连接着硬件,它是应用程序和硬件的桥梁。
内核可以进一步的划分,分为宏内核和微内核。
宏内核和微内核最大的区别就是,宏内核的用户服务和内核服务都保存在相同的地址空间中,它们都由内核进行统一管理,而微内核的用户服务和内核服务会保存在不同的地址空间中,下图可以很好的解释这一点。

其实这里的宏内核翻译过来有点牵强,其实应该叫单内核或者单核。在这种单核的设计中,内核是一个大的整体,可以说是一个大进程,在这个大进程中,所有内核服务都运行在一个地址空间中,函数之间的调用链路少,直接通信简单高效。
而微内核的功能会划分为独立的进程,进程之间通过 IPC 进行通信,高度模块化,一个服务的故障不会影响另一个服务。不过由于模块化的影响,函数之间调用链路偏长,进程之间不会直接通信,而是通过内核服务相互通信。
从内核大小上面来讲,微内核的尺寸更小,只包含用户进程相关的服务,而单核的尺寸要比微内核大的多,这点比较好理解,因为宏内核融入了太多服务和驱动。
从执行效率上来说,微内核的执行效率相对较慢,因为涉及到跨模块调用,而宏内核执行效率高,因为函数之间会直接调用。
在微内核模块化之后,它很容易扩展,因为内核空间与用户空间相互隔离,在用户态下(运行在用户空间中的应用程序)应用程序崩溃后一般不会影响到内核中的数据。宏内核的可拓展性较差。
经过上面这些描述之后,我们很容易把宏内核和微内核的特征想象成软件开发中的单体架构和微服务架构。
单体架构最大的特点就是函数调用方便,几乎不存在调用链路,一个项目解决所有问题,项目中包含数据库驱动、各种拦截器、控制器、权限控制,可拓展性非常差。
而微服务的架构之间的调用链路会比较长,模块之间的职责分离并且相互依赖,比如权限控制模块、路由模块、总线通信模块。可拓展性比较强。
这两种不同的内核结构有不同的支持者,就和有些人认为单体架构好,有些人认为微服务架构模式好。
这就像对编程语言的争论一样,你说 Python 、Go、Java 以及其他语言哪个好?管他哪个好,最终都会戏谑的称 PHP 是这个世界上最好的语言。所以,这些争论本没有意义,但是很有趣的是,这种争论常常让人想起前几年在 CPU 领域中 RISC 和 CISC 之间的斗争。
现代成功的 CPU 设计包括这两种技术中的任何一种,就像 Linux 内核是微内核和宏内核的混合产品一样。可能有些人认为 Linux 它不就是个宏内核结构么,但实际上 Linux 不单单只是一个纯碎的集成内核。
为什么 Linux 会使用单内核(此处叫单内核有点应景)结构呢?我猜有下面几个因素。
从 Linus 的角度来看,单内核的开发和选型更容易,因为避免了与消息传递架构、计算模块加载方法等相关的工作。而且 Linux 的诞生原因在于 Linus 对 MINIX(一种类 UNIX 操作系统)只允许在教育上使用很不满,再加上 Linus 本来对操作系统很感兴趣,于是他开始编写 Linux 操作系统,所以我认为当时的 Linus 开发 Linux 起源于兴趣,并未经过详细周到的设计,也并未考虑它的可拓展性。当然这只是鄙人粗浅的猜测。
这就和我们上大学的毕业设计一样,你毕业设计做的系统,你会考虑可拓展性吗?除非你想当产品来做,但是何必呢?
另一个原因是充足的开发时间。Linux 没有研发时间限制,也没有发布时间表。任何限制都只能单独修改和扩展内核。核心的单一设计内部完全模块化,在这种情况下修改或添加不是很困难。问题是没有必要为了追求未经证实的可维护性的小幅增加而重写 Linux 内核。Linus 一再强调以下观点:为了这个好处而损失速度是不值得的。
Linux 是一个借鉴了微内核精髓的宏内核结构,Linux 支持模块化的设计、抢占式内核、对内核线程的支持以及动态加载内核模块的能力。不仅如此,Linux 还避免了其微内核设计的性能损失,允许一切运行在内核模式下,直接调用函数,无需消息传递。
所以综合一点来讲,Linux 是一个模块化、多线程和内核可调度的操作系统。
模块化的设计:Linux 支持内核模块的动态加载,尽管 Linux 内核也是单核,但它允许在需要时动态删除和加载一些内核代码。
可抢占性:Linux 内核支持可抢占,与传统的 UNIX 不同,Linux 内核具有允许内核中运行的任务优先执行的能力。在各种 UNIX 产品中,只有 Solaris 和 IRIX 支持抢占,但大多数传统 UNIX 内核不支持抢占。
在 Linux 身上,完美体现了务实性。如果一项功能没有价值或创意不佳,则不会开始实施。相反,在 Linux 的发展过程中,形成了一种值得称道的务实态度:任何改变都必须针对现实中实际存在的问题,需要经过完整的设计和正确简洁的实现。
如果 Linux 是纯微内核设计,那么移植到其他架构会更容易。实际情况是,Linux 内核移植虽然不是很简单,但也绝非不可能完成的事情。
最后,给大家推荐一下我自己的 Github https://github.com/crisxuan/bestJavaer ,里面有非常多的硬核文章,绝对会对你有帮助。
聊了聊宏内核和微内核,并吹了一波 Linux的更多相关文章
- 微内核VS宏内核【转】
本文转载自:https://segmentfault.com/a/1190000002711544 内核按照体系结构分为两类 : 微内核(microkernel)与宏内核(macrokernel). ...
- spring websocket 和socketjs实现单聊群聊,广播的消息推送详解
spring websocket 和socketjs实现单聊群聊,广播的消息推送详解 WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随 ...
- Flask(4)- flask请求上下文源码解读、http聊天室单聊/群聊(基于gevent-websocket)
一.flask请求上下文源码解读 通过上篇源码分析,我们知道了有请求发来的时候就执行了app(Flask的实例化对象)的__call__方法,而__call__方法返回了app的wsgi_app(en ...
- Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序
Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...
- websocket 实现单聊群聊 以及 握手原理+加密方式
WebSocket 开始代码 服务端 群聊 # type:WebSocket 给变量标注类型 # websocket web + socket from geventwebsocket.server ...
- flask 第五章 WebSocket GeventWebsocket 单聊群聊 握手 解密 加密
1.WebSocket 首先我们来回顾一下,我们之前用socket学习过的项目有: 1.django 2.flask 3.FTP - 文件服务 HTTP - TCP (特点): 1.一次请求,一次响应 ...
- websocket 群聊单聊
websocket 介绍 介绍引自 https://segmentfault.com/a/1190000012709475 群聊 from flask import Flask, request, r ...
- websocket 群聊,单聊,加密,解密
群聊 from flask import Flask, request, render_templatefrom geventwebsocket.handler import WebSocketHan ...
- Flask请求上下文源码讲解,简单的群聊单聊web
请求上下文流程图 群聊html代码 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...
随机推荐
- PHP中的文件系统函数(二)
这次我们来学习的是一些不是太常用,但却也非常有用的一些函数.它们中有些大家可能见过或者使用过,有一些可能就真的没什么印象了.它们都是 PHP 中文件系统相关操作函数的一部分.存在即合理,或许只是我们的 ...
- 3gcms-Flash幻灯片上传后图片模糊解决办法
很简单,不用纠结,直接修改admin/lib/action/FileAction.class.php 将 $upload->thumbMaxWidth='300'; //以字串格式来传,如果你希 ...
- Groovy系列(4)- Groovy集合操作
Groovy集合操作 Lists List 字面值 您可以按如下所示创建列表. 请注意,[]是空列表表达式 def list = [5, 6, 7, 8] assert list.get(2) == ...
- AT2305-[AGC010D]Decrementing【博弈论】
正题 题目链接:https://www.luogu.com.cn/problem/AT2305 题目大意 \(n\)个数字两个人进行博弈,每个人的操作为 选择一个大于1的数字减一 之后所有数字除以所有 ...
- 深入浅出WPF-08.Event( 事件)02
路由事件 为了方便程序中对象之间的通信常常需要我们定义一些路由事件.使用路由事件比直接事件方便得多. 创建自定义路由事件的步骤: 1)声明并注册路由 2)为路由事件添加CLR事件包装 3)创建可以激发 ...
- Go变量与基础数据类型
一.基础介绍 Go 是静态(编译型)语言,是区别于解释型语言的弱类型语言(静态:类型固定,强类型:不同类型不允许直接运算) 例如 python 就是动态强类型语言 1.Go 的特性: 跨平台的编译型语 ...
- ajax 中文参数乱码问题不一定是编码格式问题。
代码要修改用户的信息,写了三个ajax,第一个写完测试没有问题,后面俩逻辑一样的就直接复制粘贴了.到第二个ajax测试的时候发现中文会乱码 如下 $.ajax({//中文参数乱码 url: '/edi ...
- 从一个舒服的姿势插入 HttpClient 拦截器技能点
马甲哥继续写一点大前端,阅读耗时5 minute,行文耗时5 Days 今天我们来了解一下如何拦截axios请求/响应? 这次我们举一反三,用一个最舒适的姿势插入这个技能点. axios是一个基于 p ...
- 怒肝 Linux 学习路线,这回不难
Linux 学习路线 by 鱼皮. 原创不易,请勿抄袭,违者必究! 大家好,我是鱼皮,又花 1 周肝出了 Linux 学习资料全家桶,包括学习路线.命令手册.视频.书籍.文档.实战教程.社区.工具.大 ...
- node-gyp项目命名BUG
当我们编写node原生模块的时候,免不了对node-gyp项目进行命名,在node-gyp进行build的时候,会跟binding.gyp配置文件中的target_name生成对应的原生模块.但是,如 ...