移植之乱谈

简介: 昨天有一个博友回复,说他已经完成了android系统在windows上的移植,其中比较难的是binder系统的移植。下面是两个demo网址,我看了后倍有感触。http://v.youku.com/v_show/id_XMzIwMDkxOTQ4.htmlhttp://v.youku.com/v_show/id_XMzIwNzI2NTg4.html这才是真正有技术含量的移植啊!从做android开始,听到的最多的就是移植+merge了。

昨天有一个博友回复,说他已经完成了android系统在windows上的移植,其中比较难的是binder系统的移植。下面是两个demo网址,我看了后倍有感触。

http://v.youku.com/v_show/id_XMzIwMDkxOTQ4.html
http://v.youku.com/v_show/id_XMzIwNzI2NTg4.html

这才是真正有技术含量的移植啊!

从做android开始,听到的最多的就是移植+merge了。但总感觉都是:

1 简单的把人家做好的,放到新的平台上,然后测试,修改。完完全全的改bug。甚至都不需要对系统,程序结构有什么深入的了解。

2 做linux驱动更是这样,到处去改参数,调板子。(个人感觉都被硬件绑架了..)。

什么后果?居然很多人一年都写不了几行代码!!!我知道google有一个美女程序员,每天都要花4个小时来写代码,没有什么别的特殊目的,就是为了保持脑子的灵活。

另外,那些刚工作的人,改改bug就完成工作,而又不写代码,让他们误以为程序员就是这样工作的,结果不去花时间研究系统(放着linux内核,android系统这种高质量,高复杂度的优秀源码不看。说实话,代码量不超过10w行以上的同志,真的怀疑能否看懂代码的真正意图,所以google校园招聘的时候,似乎对代码量有一定的要求),

【这里也请那些培训学校的老师们,稍微注重下教育质量,培训方法。】

我心目中的移植,是应该建立再对当前平台和目标平台的一个深刻认识上,再加上对要移植代码本身,程序结构得深入了解上才能做的。看看上面博友的移植,如果只会改几个bug,何年何月才能将android系统移植到windows上呢?

下面是我之前做的一份关于完成端口到linux平台上的移植的设计文档。这个设计由于各种原因,最终没有被讨论过,也没有(永远不会)被采用。

                    <strong>完成端口在Linux平台下的实现 一 说明</strong>
 
Windows下的完成端口模式是一种真正的由操作系统来实现的“异步IO”,应用程序等待完成通知即可。
 
在面向对象的网络库中,包括ACE, ASIO, LibEvent, SPServer等开源公共库中实际有类似的模块。一般将完成端口模型称之为Proactor模型,而select的方式称之为Reactor模型。
 
简单来说,在Reactor模型中,系统通知你可以干什么,然后应用程序去做对应的事情(例如send,recv,accept等)。以发送为例,流程大致如下:
 
1  用户注册回调事件
 
2  Reactor等待select返回,然后调用回调
 
3 用户在回调中继续发送操作(非异步IO)
 
而在Proactor模型中,系统通知你什么已经干完了(例如上一次send完成了,recv完成了,accept完成了)等,仍以发送为例,流程大致如下:
 
1  用户注册回调,发送数据(异步IO)
 
2  Proactor检测发送完成事件,然后调用回调
 
3  用户在回调中继续发送操作(异步IO)
 
从流程上看,似乎没有区别。而关键点就在于IO是否为异步。Reactor模型一般是非异步的,而Proactor由于能检测完成事件,所以IO是异步的。
 
在Linux平台上,由于系统并没有支持异步IO,所以我们必须用Reactor的模式去模拟一个Proactor模式。大体流程如下;
 
1 用户注册回调,发送数据(非阻塞IO)
 
2 构造一个完成事件,记录发送的结果,并添加到完成事件队列
 
3 Proactor检测完成事件队列,然后调用回调
 
4 用户继续发送数据(非阻塞IO)
 
从上面可以看出,在Linux下Proactor的实现关键是自己构造一个完成事件队列,并处理相关入队和出队的操作即可。这种实现方式与windows完成端口是一致的。
 
从已知的资料来看,Proactor模型本身没有设计缺陷。我们将参考Windows下的完成端口的原理和用法来实现一个Linux平台下的完成端口。
 
  
 
<strong>二 设计细节</strong>
 
与完成端口相关的有线程池,完成端口句柄,和完成事件队列。
 
1 完成端口句柄:将与一个epoll句柄相对应
 
2  线程池:调用GetQueuedCompletionStatus从完成事件队列中取事件
 
3  用户调用IO操作,将事件加入完成队列
 
<strong>2.1 事件入队</strong>
先讨论事件入队的操作。有两种明显的方式来完成。
 
这里所有的socket或者别的文件句柄必须都是非阻塞的。
 
<strong>1, 真正的异步IO</strong>
 
要实现真正的异步IO,需要有一个线程池来完成实际的IO工作,并且还需要有一个IO请求队列来保存用户提交的IO操作请求。在Windows平台下,这个线程池和队列是位于操作系统内部的。而在Linux平台上得自己创建相关组建。
 
工作流程如下:
 
1 用户发起IO操作,内部创建一个IO请求,并加入到请求队列
 
2  内部线程从请求队列中取出请求,完成实际的请求,并将请求结果加入到完成端口的完成事件队列
 
这种方式的优缺点有:
 
1  优点,很大程度上的异步IO。(其他的优点暂时未想到)
 
2  缺点:实现难度较大,而且资源消耗比较多
 
<strong>2. 利用非阻塞模式构造的伪异步IO</strong>
 
在这方式下将在用户调用的IO函数中直接完成实际的IO操作,只不过不阻塞罢了。这种方式可以不需要IO请求队列,不需要线程池。
 
考虑目前的并发数量,暂时用方式2来实现。
 
  
 
<strong>2.2 一些不能完全实现的地方</strong>
Windows下有些用法在Linux没有合适的模型对应,包括:
 
1  AcceptEx对应的先创建socket以供AcceptEx使用的方法
 
2  GetAcceptExSockAddr
 
实现过程中,将尽力保证接口的一致。
 
<strong>2.3 涉及的内容</strong>
模块上,可能包括:
 
1 完成端口相关函数和类设计
 
2 已有windows下的线程池到Linux平台下的移植
 
3 Socket相关库的修改与异步IO配套功能的增加
 
性能考虑方面,目前可以想到的包括:
 
1 池的和自旋锁的使用
 
2 GetQueuedCompletionStatus函数的内部实现要考虑使用刚完成工作的那个线程来继续工作,以避免不必要的线程切换
 
3 同理,PostQueuedCompletionStatus函数内部要避免触发所有线程来竞争一个事件的出队

  

回想当时做这个移植,花了很多时间来调研完成端口的实现机制,来研究proactor和reactor的区别,来研究linx平台的特性。考虑到完成端口是Win平台最有效率的IO操作,那么在linux平台上实现自然也得考虑效率方面的问题。

虽然最终没有实现该设想,但却极大加深了对以上知识的认识,对以后的工作有非常大的帮助。

作为本篇的结尾,希望大家认真对待工作,从简单的移植工作中去发掘背后那块绝大的金矿,以提高自己的价值。

谢谢大家对《深入理解android 卷I/卷II》的支持。
目录
相关文章
|
SQL 监控 NoSQL
架构师第一课,一文带你玩转 ruoyi 架构
我理解的架构/框架应该有以下功能: 1.满足日常开发功能,如单点登陆、消息队列、监控等; 2.规范开发者的开发,指定代码格式、注释等; 3.提高开发效率,提供一系列的封装方法,并减少bug的产生率。 下文将详细介绍ruoyi框架。
8156 1
架构师第一课,一文带你玩转 ruoyi 架构
|
关系型数据库 数据库 数据安全/隐私保护
Docker-10:Docker安装PostgreSQL
通过容器化Docker 安装 postgrel
5698 0
Docker-10:Docker安装PostgreSQL
|
10月前
|
缓存 NoSQL Java
高并发场景秒杀抢购超卖Bug实战重现
在电商平台的秒杀活动中,高并发场景下的抢购超卖Bug是一个常见且棘手的问题。一旦处理不当,不仅会引发用户投诉,还会对商家的信誉和利益造成严重损害。本文将详细介绍秒杀抢购超卖Bug的背景历史、业务场景、底层原理以及Java代码实现,旨在帮助开发者更好地理解和解决这一问题。
310 12
|
12月前
|
Java Python
Python 生成、解析二维码
Python 生成、解析二维码
259 0
|
机器学习/深度学习 人工智能 数据可视化
斯坦福博士图解AlphaFold 3:超多细节+可视化还原ML工程师眼中的AF3
【8月更文挑战第8天】AlphaFold 3作为AI领域的重大突破,革新了蛋白质结构预测。斯坦福博士通过图解详析了其内部机制,展示了多尺度建模与图神经网络技术如何提升预测精度。尽管存在数据依赖性和计算成本等挑战,AlphaFold 3仍极大地加速了生物学研究与药物开发进程。论文详情参见:https://www.nature.com/articles/s41586-024-07487-w
517 4
|
边缘计算 JSON JavaScript
一起来学 next.js - API 路由篇(轻松做全栈?)
next.js 作为最热门的 react 框架,不过这么久了好像国内使用率一直不太高。最近在研究做个小项目正好做下笔记,有兴趣的可以一起来学习。
|
Java Android开发
UsageStatsService详解
UsageStatsService详解
252 0
|
人工智能 搜索推荐 Linux
一个集 AI + 工具 + 插件 + 社区为一体的Arc 浏览器风格AI客户端
一个集 AI + 工具 + 插件 + 社区为一体的Arc 浏览器风格AI客户端
491 0
|
SQL 关系型数据库 MySQL
MysqlClient安装步骤详解
MysqlClient安装步骤详解
2405 0
|
SQL Apache 流计算
Apache StreamPark系列教程第一篇——安装和体验
Apache StreamPark系列教程第一篇——安装和体验
1177 0