思考系统API设计的问题

标签: 思考 系统 api | 发表时间:2010-12-01 21:28 | 作者:flagman edware_love
出处:http://www.cppblog.com/

最近正好在思考系统API设计中考量的一些问题,

【某网友讨论到】
: 那地址是不是同一个地址呢。我现在的理解是这样的,假设有巨大的真实内存。windows首先将高2G的内存自己占了,用作各种内核对象。这2G内存共享给每个进程,但进程不能直接访问,只能通过windows给定的函数访问。
: 然后每个进程都给他2G内存,进程如果创建自己的对象就放到自己那2G内存里面,如果要建立内核对象就放到共享的那高2G里面去。
: 所以不同进程如果可以访问高2G内存的话,任何进程访问到同一个高地址实际上都是访问到同一个对象。但如果访问低2G地址的话,不同进程是对应不同的对象的。



在不同的进程中,询问同一个内核对象的实际地址(无论是线性地址还是物理地址),是无意义的:

首先,内核对象只能由在内核态下的例程才能直接访问,在我们日常的代码中,所调用的Windows API,比如CreateFile, (注意调用刚开始时是处于用户态下的),一般都会在ntdll.dll中找到对应的内核函数或例程,接着系统切换到内核态,开始调用实际对应的内核函数(KiCreateFile),这个时候才会去访问内核对象的实际地址,然后建立一个该内核对象对应当前进程的Handle,并把它返回给caller,同时切换回用户态;因此,对于用户态程序来说,只要且只能知道该内核对象在当前进程中的对应的Handle就可以对其进行操作了;

其次,这样的设计是出于对OS核心数据结构(当然包括我们正在讨论的内核对象)的保护;如果用户态程序可以轻易的获取内核数据结构的实际地址,那么对于整个OS的安全和稳定显然构成很大的问题;一个用户态的误操作可以轻易的引起整个OS的崩溃,而有了这一层的保护,崩溃的只是当前进程而不是整个系统;

接着上面这点,也可以看出,内核对象的如此设计达到了接纳OS本身的平滑演进的目的。从Windows 3.0到95/98,从NT到Win2k/XP,再到眼下的Vista/Win7,Windows操作系统本身发生了巨大的变化和进步,采纳了无数的新技术新方法,但是它基本的系统应用编程接口,也就是我们所熟知的windows API,却并没有发生太大的改变,很多Win 3.0 这个16位OS时代的程序代码只要当初设计规范编码规范,稍许修改就可以在最新版的OS上运行如飞;是什么做到了这些?也就是所谓的极为重要的向后兼容性,我个人认为,把操作系统的重要/主要功能抽象成内核对象,并通过一套极为solid的API暴露出来,达成了这个目标。

这是一种更高层次上的面向对象,把实现的细节,把系统的复杂,简单而优雅的封装了起来。你只要调用CreateFile去建个文件或管道或邮槽,不用担心当前OS是Windows 3.0还是Win7,获得的Handle,你也不用去关心它以及它所指向的内核对象是Windows 3.0的实现还是Win7的实现。

Windows上所有的精彩几乎都是基于这套通过内核对象概念抽象并暴露的API基础之上,COM/OLE,这个二十年前震撼性的ABI和IPC范畴的技术规范,其中很多的设计思路也是植根于内核对象的设计理念,如COM对象的引用计数和内核对象引用计数,IUnknown和Windows Handle(前者是指向某个二进制兼容的组件对象,后者引用或间接指向某个内核对象,都是对于某个复杂概念的一致性抽象表述),等等;

十年前的.net,本来是作为COM的升级版本推出,把COM/OLE的实现复杂性封装在了虚拟机平台CLR里面,而从这个虚拟机的开源实现SSCLI,我们可以看到大量的COM机制在.net的具体实现里面起了举足轻重的作用。在这些VM中大量symbol有着COR的前缀或者后缀,COR指代什么?Common Object Runtime, 原来CLR/SSCLI的设计思路也是把OS通过虚拟机VM的形式,并通过common object向应用程序暴露功能。

小结一下,
OS内核对象API,三十年前系统级别的对象抽象;
COM/OLE,二十年前二进制组件级别的对象抽象;
.net/CLR, 十年前虚拟机平台级别的对象抽象;

写到这里倒是引起了我其他的一些思考,软件工业界一直以来对面向对象OO是热火朝天,特别是语言层面,从C++/Java/C#到Python/JScript,不一而足;

但是我们有没有从根本性的设计理念上对面向对象,察纳雅言了呢?

如果现在设计Windows这套API的任务放在大家面前,会采用内核对象/Handle方案还是直接指向OS内部数据结构的方式来暴露功能?

从三十年前的这套API的设计中,我们真的可以学到很多。


 



flagman 2010-12-01 21:28 发表评论

相关 [思考 系统 api] 推荐:

思考系统API设计的问题

- edware_love - C++博客-首页原创精华区
最近正好在思考系统API设计中考量的一些问题,. 我现在的理解是这样的,假设有巨大的真实内存. windows首先将高2G的内存自己占了,用作各种内核对象. 这2G内存共享给每个进程,但进程不能直接访问,只能通过windows给定的函数访问. : 然后每个进程都给他2G内存,进程如果创建自己的对象就放到自己那2G内存里面,如果要建立内核对象就放到共享的那高2G里面去.

API快速开发平台设计思考

- - DockOne.io
在我之前谈API网关的时候曾经谈到过快速开发平台,即将API快速开发的一些内容放入到API网关中,实际来看围绕API全生命周期管理,本身包括了开发态,运行态,运维态. 对于API网关更多的是解决运行态的问题,API网关本身应该轻量化设计,不做太多的协议转换,适配,数据映射等工作,这些工作应该放到API开发平台来完成.

《系统思考》读后感

- 章明 - 所有文章 - UCD大社区
经别人推荐(都忘了是谁推荐的了~),买了这本《系统思考》,看完前几章,发现这是一本非常好的书. 全书的精华也都在前面几章,后面都是一些具体的案例分析. 为什么必须从整体研究系统. 将系统分块通畅破坏了你所试图研究的系统. 如果你破坏了系统内的连接,你就破坏了系统本身. 更奇妙的是,很多系统表现出他们的任何组成部分都不具备的特征.

Filer.js:简化HTML5文件系统API开发的开源JS库

- - HTML5研究小组
在 W3C 的工作草案中,有一个雄心勃勃的底层 Web 标准开发计划即 HTML5 文件系统(Firesystem)API 规范. 所谓 Filesystm API 是一个提供在用户自定义的沙盒文件系统中读取与写入文件及目录的接口. 不过正如文件系统一样,该 API 代码较长而且复杂.   为此 Google Chorme 团队的工程师 Eric Bidelman 写了一个基于它的 JavaScript 包装库,Bidlelman 将其命名为 filer.js 并放在了 GitHub 上.

有道Kubernetes容器API监控系统设计和实践

- - DockOne.io
【编者的话】本篇文章将分享有道容器服务API监控方案,这个方案同时具有轻量级和灵活性的特点,很好地体现了Kubernetes集群化管理的优势,解决了静态配置的监控不满足容器服务监控的需求. 并做了易用性和误报消减、可视化面板等一系列优化,目前已经超过80%的容器服务已经接入了该监控系统. Kubernetes 已经成为事实上的编排平台的领导者、下一代分布式架构的代表,其在自动化部署、监控、扩展性、以及管理容器化的应用中已经体现出独特的优势.

开源API越权漏洞检测系统推荐:IDOR_detect_tool

- - 程序猿DD
相信大部分读者跟我一样,每天都在写各种API为Web应用提供数据支持,那么您是否有想过您的API是否足够安全呢. Web应用的安全是网络安全中不可忽视的关键方面. 我们必须确保其Web应用与后台通信的安全,以防止数据泄露,因为这可能导致重大的财务损失和声誉受损. 而在Web应用的安全问题中,最常见的漏洞之一是不安全的直接对象引用,简称:IDOR.

Api Blocking

- - xiaobaoqiu Blog
4.RateLimiter实现限流. 接口限流是保证系统稳定性的三大法宝之一(缓存, 限流, 降级).. 本文使用三种方式实现Api限流, 并提供了一个用Spring实现的Api限流的简单Demo, Demo的git地址: https://github.com/xiaobaoqiu/api-blocking.

财务系统设计的思考

- - 行业应用 - ITeye博客
说到财务系统的设计,就不由得联想到了目前很流行的一个职业“互联网产品经理”,他们的设计着眼于用户体验,创造出新的功能,改善着上亿网民的生活,比如扫一扫,摇一摇等. 财务系统不同于互联网的产品,它的复杂性对于没有深入了解它的人来说,是不太能想象出来的. 互联网的功能开发,讲究的是时效,从一个点子,到产品发布可能只用一周的时间,然后如果市场冷淡,可能第三周就下线了.

股票API

- 狗尾草 - 博客园-首页原创精华区
股票数据的获取目前有如下两种方法可以获取:. http/javascript接口取数据. 1.http/javascript接口取数据. 以大秦铁路(股票代码:601006)为例,如果要获取它的最新行情,只需访问新浪的股票数据. 这个url会返回一串文本,例如:. var hq_str_sh601006="大秦铁路, 27.55, 27.25, 26.91, 27.55, 26.20, 26.91, 26.92, .

API 与 ABI

- Ant - A Geek's Page
(本文亦是《C语言编程艺术》中的一部分,所以请勿用于商业用途. 一些程序员居然对API和ABI这两个概念都不清楚,我感到有些惊讶. 这里以 Linux 内核为例简单解释一下. API,顾名思义,是编程的接口,换句话说也就是你编写“应用程序”时候调用的函数之类的东西. 对于内核来说,它的“应用程序”有两种:一种是在它之上的,用户空间的真正的应用程序,内核给它们提供的是系统调用这种接口,比如 read(2),write(2);另一种就是内核模块了,它们和内核处于同一层,内核给它们提供的是导出的内核函数,比如 kmalloc(),printk().