机器人第四定律

从前面一个post关于资源管理想到的

资源管理的方式,可以让程序员定义的“任务”通过系统调用注册到系统里,然后这些任务以自我繁殖的方式,不断复制。缺乏资源的任务会被“饿死”(starving),这样同时解决了死锁问题。而占有资源可以正常工作的任务就会不断繁殖。如何防止资源过度利用?可以设置一个人口密度的概念,当同种群的任务在系统中的密度过大时,繁殖速度就会下降,保持到均衡的状态。

最后,咱忽然想到的就是,必须给所有的任务一个开关,可以手动关闭一个任务。

这还远远不够。还需要能发出一个信号杀死所有的同种群任务,以及杀死所有的任务。

其实这也是我对于人工智能思索了很久以来的一个结果。想要保证人工智能的安全性,如果从fundamental 做好定义,让人类对所有的人工智能都有一个最高的控制权限的话,基本上就可以防止天网入侵了。或者你遇见终结者的时候,只要说出一条密码,所有的终结者,乃至所有的人工智能都会执行自毁程序,那即使天网入侵了你也不会惧怕。

我相信假如人工智能出现,他一定是建立在自动化的单元测试基础之上的。他会迅速地变异,修改自己的代码和功能,然后跑单元测试,如果通过率比过去更好,则保留这个变异方案。只要把上述人类对人智的控制作为最最基本的BVT单元测试,在开发人智之初就放进去,则无论未来的人工智能如何变异如何强劲,都可以保持在人类的掌控之下。

这就是我想要补充的机器人第四定律:

vi. 当人类提出自毁信令,根据该信令特权级必须做如下操作:

特权级2,本单位自毁

特权级1,广播信令,完成种群自毁(任何本种群的人智接收到这个信号后,广播该信号一段时间,接收到ping back或者超时后,完成本单位自毁)

特权级0,广播信令,完成类别自毁(如前,但范围扩大,所有继承自一棵遗传树的人智均执行自毁)

 

啊啊啊,继续沿着这个思路想象下去就是一部科幻小说了啊啊啊

论资源抢占的系统设计

怎么会想到这个问题,出发点是来自提出一个更通用的多线程架构的问题。其实这个问题我现在讨论有点过早,因为至今还没仔细研究过go和erlang,不了解多线程编程的现状。但总归在这个blog的小小圈子里,随便抒发几句应该是问题不大。

其实我的想法是很简单的,就是想增加一个 “任务” 的概念。这个必然很多语言很多系统已经提供了,我为什么还要提。我主要是感觉,现在的多线程编程,还有网络编程,每个程序都自己定义一套多线程管理、进程池、线程池、网络连接池、数据库连接池等等概念。虽然有库函数,不必每次从头造轮子,但每个程序一份几乎完全雷同的管理机制,绝对是有问题的。

况且,现在的操作系统,除了CPU占用这一点实现了“抢占”之外,其他的系统资源仍然是依赖程序间的谦让协作的。我前几天发的帖子,就是因为adb的一个bug,导致占用了过多的系统连接,导致其他程序无法使用网络。同样的例子,臭名昭著的迅雷,因为过量占用连接数导致你根本无法上网。虽然最近迅雷提供了种种功能,他会检测你有没有使用浏览器,他会检测某些著名的端口(对应各大著名网游),确定你是不是在打游戏,等等,来谦让地给你腾出一些网络带宽。但问题是,这样看来,是不是太委屈迅雷大哥了。虽然霸占过多网络资源是他的不对,但是研究到底应该使用多少资源,并不是一个应用程序能够做到的事情(迅雷也只是经验性的猜测,你自己写的网游、小众的网络服务,他一定是无法猜测到的)。

参考CPU抢占的系统设计,其实资源抢占完全也是可以做到的。还可以参考虚拟内存的方式,给每个应用程序足够巨大的虚拟资源空间,并使用工作集、缺页调度等机制,调度所有的资源。这样擅自开辟了大量网络连接的服务(如adb),也不会导致系统无法打开更多的网络连接,霸占了大量资源的迅雷,也无法阻止其他程序连接网络(因为有工作集的限制)。操作系统可以根据资源使用的活跃程度等因素调度资源,例如当其他程序都不使用网络时,就可以让例如迅雷这样开辟了过多连接的程序拥有更大的工作集,保证系统资源的最大化利用。

好吧,话说到这里已经扯开去了。前面提到的多线程管理的机制,其实跟这个资源抢占的机制没有任何关系。只是因为思路飘忽扯到这里来了。说回那个多线程管理的问题,也是一样的,我希望提供一种机制说明任务的并发逻辑(可能要使用新的语言,至少C语言无法表达并发逻辑这种概念),然后要使用什么样的并发度,这个决定让系统来做。因为系统有多少内存资源,有多少CPU资源,这些事情本不该是应用程序该知道、该负责的事情。尤其是,跟本身的应用程序一起,系统里还有哪些其他的程序在跑,他们对内存和CPU的消耗如何,更加不是应用程序的职责范围能知道的。但是决定一个任务的并发度,必须从系统级思考问题。因此把并发逻辑列清楚之后,让系统去决策如何并发,才是最良好的策略。我不知道go语言或者erlang这些传说有着高度并发支持的语言是否已经做到这样,如果是这样的话,我就再次后知后觉了;不过作为一个思考练习,也是挺好的~(热烈欢迎评论拍砖=)

好吧,把资源抢占和这个多线程管理机制综合到一起,就变成了更系统更完善的系统管理机制。因为并发度不仅要考虑内存CPU,也要考虑硬盘、网络、设备等等等等。把所有的资源使用频率整合统筹调度,就能得到最优化的系统,当然这个多维度的最优问题,也将成为一个巨大的算法难点。也正是因为想到这里,我才感到格外兴奋。

说实话,即使用十年时间去开发出来这样一个系统也不会太迟。但要做到一点,就是对市场现有产品的兼容性。如果能运行java虚拟机,或者能兼容linux系统调用(也就是说新系统在linux的基础上修改得到,说实话我觉得这是一个靠谱的打算),或者至少旧有的程序代码通过编译能够运行在新的系统上,并且仍能体现系统的优越性,那么新东西做出来就不会没有市场没有价值。

不过我真的要跳这么个大坑么。。还是仅仅满足于YY然后坐看系统更替风云变幻?说实话,自己感觉暂时能力有限不足以完成伟任呢,或者说过于浮躁也有可能。暂时先记录一下吧,也许明天就会自否命题了呢囧|||

有时间先去研究下go和erlang哈哈:)

PS. 还有一个关于通用缓冲区设计的思考练习,目前正在开发和实验中,有结果了一定写bo!

google search image by image

我记得大一的时候姚俊光同学提出的创新计划就是类似的事情吧。

如今google大哥已经可以做了,而且是做的相当好。

其实去年google推出拍摄照片搜索地址,还有拍摄照片搜索品牌的时候,就感觉到这个气味了。

只是可能他的算法还不够成熟吧,他要一鸣惊人这种效果。

现在这个效果,绝对可谓惊人了。

是吧。

心甘情愿给他免费做广告啊啊啊啊。。。

他的图片说明是自动生成的,确实厉害。

不知道我这么搜索一次,能耗多少电创造多少二氧化碳呢,哈哈> <

 

android adb fail

adb 在我的机器上启动了无数监听线程……

居然把我系统的网络缓冲区用光了……

说实话,这还是头一次看到别人写的程序导致这种错误|||(一般都是咱自己搓是吧…

这叫做内存泄漏啊,这叫做套接字泄露啊,严重产品问题啊……adroid不能只注意产品质量,也要注意开发工具的质量啊,否则谁愿意给你做东西啊。

北京出差

好久好久没有写bo了。。
上班以后确实挺累的,回家里就翻在那里,看会动画片,然后睡觉…囧|||

终于因为出差的关系,手上的工作都交接了,反而可以悠闲地打打酱油神马的~
所以,装了个highlight的工具,试试效果哈~


#include <stdio.h>
int main(){
    printf("hello, world\n");
    return 0;
}

嘿嘿比如
http://www.hawkwithwind.net/blog/2011/03/11/linux内核学习-c风格的面向对象/
http://www.hawkwithwind.net/blog/2010/11/26/linux发烧/
这两篇也挺好的~

但是他这个关键字匹配的方法,不是语法分析,很多都识别不出来。。不过咱已经满足了呵呵

windows UNC path

原来windows可以支持这种UNC的路径名,甚至用fopen的时候也可以用UNC。全称叫做Uniform Naming Convention.

UNC就是在路径名前面加上\\?\符号。虽然在资源管理器里面不能用,但在浏览器的地址栏里面输入这种类型的路径是可以访问的。例如 \\?\D:\ 之类。

某些时候挺有用,例如路径名长度超过249的时候,或者要访问samba服务器上的资源的时候。做个记录。

Symbian 系统学习-活动对象和其他

最近做了一个android monkey test到symbian的移植。算是草草学习了一下symbian系统吧。写一些东西做个记录,方便以后自己查阅。

symbian系统最有意思的设计应该是这个Active Object的设计模型了。他使用非抢占的多任务模型,固定优先级。这个非抢占我一开始理解得不够好。后来做monkey的时候,用的console程序。想在里面用CActive做进程监视,发现他的RunL函数永远都无法进入。跟公司的symbian大牛也讨论了好久都没有解决问题。最后还是自己悟了。这个所谓的非抢占,就是说你console的主函数不退出的话,这个Active scheduler是不会调度的。之所以那位大牛写的demo可以运行起来,是因为他用的是窗口工程,在一个窗口回调函数里面调用的SetActive。窗口回调函数退出之后自然而然Active scheduler就会调度了。而且估计这个窗口消息的处理,symbian也是采用Active Object来实现的。

我本来以为,只要我在主函数里面调用一个引发调度的函数就好了。我想当然地调用了sleep函数,然完全没有效果。还有后来改用User::After函数,也完全没有用。我后来想,论坛上经常有人提醒说,这个User::After函数是同步的。究竟有多同步,这我才知道了。就是说他也是不会引发AO调度的。这样一想也是可以理解的。因为他说的是非抢占嘛,就是说如果你睡眠了把CPU让给别人,等你到了该睡醒的时间,别人正在运行,那你就没有机会再把这个CPU抢占回来了。假如说做成双方都可以互相协作让CPU的,那基本上就算是协程了。这里的AO,如同网上一些讨论一样,应该算是“纤程”吧,可惜还没腾出时间去仔细研究他。本来想仔细去研究一下AO调度,究竟哪些函数(确切的说应该是系统调用)是可以引发AO调度的,但毕竟还是公司的任务优先吧,这个没有去细查,用了另外一个进程,乖乖写成窗口程序来做了。有机会的话以后再来改吧。

Symbian另外一个有意思的设定就是process崩溃之后不会立即退出。而是会继续保留一段时间,之后系统会把这些死进程统一回收。一开始还不是很理解他为什么要这么做,可是后来做进程监视的时候就发现,这个设定非常好用。你可以在进程崩溃之后,再去遍历系统的进程表,然后找到有问题的进程(他的退出码会是负数),然后找到具体的错误原因。其实这个工作就叫做“验尸”,而且symbian也提供了一些验尸工具去帮助调试。这样就给了系统调试很大的自由空间。否则的话,必须在一开始就确定监视哪些进程。假如有些进程,例如我现在在调试的这个(哔—),他是随着用户操作过程中而时而启动时而退出的,你很难去一直捕获着他,去监视他的运行情况。

还有一个就是本来对于symbian程序员来说是司空见惯的东西吧,就是这个清除栈CleanupStack,还有对象的所谓二次构造,以及symbian自有的一套类似于try catch的机制,是用的Leave和trap来实现。这些东西应该就是symbian的系统特点了吧,其他系统上是绝对见不到这些东西的。从异常安全的角度来说,这个二次构造真的是合理的设计吗?我觉得也不见得。不过他配合清除栈的使用,确实能够保证内存泄漏。这在内存紧缺同时开机时间甚至可能长达数年的嵌入式产品来说,的的确确是至关重要的。否则即使是非常微小的内存泄漏,假如连续开机数年(这里肯定不是手机啦,比如说是电冰箱咖啡壶什么的),还是会引起系统崩溃的。

最后就是监视到进程崩溃如何获取调用栈信息的问题。本来的想法甚至是去获取CPU寄存器的值,然后根据可以得到的线程列表中获取到的堆栈地址的信息,配合编译过程中生成的.exe.map,进行函数地址对比,从而得出调用信息。后来发现这种事情不用自己去做(而且在用户这个层次应该是很难获取到CPU寄存器的值的吧)。symbian提供了一个很好的内核调试工具,d_exc.exe,可以在系统中有任何进程崩溃时记录调用栈信息。需要的只是去把这个程序在测试开始之前运行起来就好了。至于symbian的内核端调试,nokia wiki上有一篇很好的文章,我还没找时间好好研究,这里也先记在这里kernel side debug

好啦今天的笔记就做到这里。并非是API介绍,假如说有人有兴趣想知道具体的内容的话,这里特别推荐的是nokia官方论坛的wiki,内容非常充实,对于我这样的初学者来说,非常有帮助。
例如这篇process monitor,还有这篇process and threads, how to find them等等。