9

利用编译技术异步转同步想法

 3 years ago
source link: https://www.zenlife.tk/value-of-k.md
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

利用编译技术异步转同步想法

2016-05-15

写事件回调的代码把自己恶心着,思考有什么更好的做法,因为这个问题不是困扰一回两回了

去网上搜一搜,也发现什么建设性的东西,都是存在已久的话题了。查了一下promise,感觉这就是一个first class的callback的东西。callback是反人类的,这一点它没有改变本质。

知乎看到一个回答:

callcc 是功能集最小的。 程序员最容易接受的是 coroutine。

Belleve确实是极少数既理解本质并且洞察到方向的人。但是又有个蛋用呀!需要的是要解决方案。最近在写rust,在一门不支持coroutine的语言中,该怎么做?

原生语言里面实现协程库的方案很久以前我就尝试过,是有一些问题的。协程的切换需要保留上下文信息,所以都要有独立的栈。为了轻量这个栈的内存就不能太大,那么就必然面临栈扩容问题。栈扩容可以segment stack或者连续栈两种方式,前者需要很恶心的汇编,后者原生语言里其实是做不了的,因为有对象会引用到栈里面的地址,而分配一块新的栈后内存地址的引用就失效了,为了补救需要更新所有引用了老的栈地址的对象。Go可以做是因为它有运行时,垃圾回收有类型信息,它认识栈里面每块空间是什么对象,所以知道栈扩容后怎么更新引用。

这个方案我基本认为走不通。

突然脑洞大开想到一个点子。想法是这样的:利用编译技术,其实很容易把控制流暴露出来。我们可以写一个很特别的"编译器",这个编译器专门做的事情就是负责把同步代码编译成异步。然后在不支持coroutine的宿主语言那边写一个库,这个库会执行编译后的代码。

前半部分是同步转异步的翻译过程,用我们自己写的语法,编译时暴露出控制流,发现执行可能会阻塞时就切换。后半部分的库其实是一个解释器,不管是采用字节码或者其它形式。达到的效果就是我们可以用同步的思维去写代码,而底层其实是基于异步的。

不管什么样实现,控制流的切换都是需要涉及到上下文信息的。那么这个方案跟原生语言里做协程库有什么不同呢?其实这是一个interpret的协程方案,这个库就是interpret。控制流已经在前面编译的那个环节暴露出来,interpret可以实现切换自己的上下文。

会遇到的一个问题是,原生->解释器->原生,这种栈交错。如果存在这种栈交错,就无法切上下文了。好在可以保证的一点不会发生,因为遇到切换时一定会先从原生退回到解释器那一层,这样我们的上下文就全部是保留在解释器层的。

如果还是不能理解,就想一下,lua为什么能实现协程。这里想做的事情无非是这种场景的一个特化,即利用解释器这一层的协程来做同步转异步。

有idea就控制不住想试试。开始我想写成这样子

((compile exp) env cont)
LiSP第6章的编译器。但是发现如果这么做,宿主语言那边env和cont都要做成寄存器,那就需要实现一个小的虚拟机了。SECD虚拟机虽然不难,但是这样子就有点杀鸡用牛刀的感觉了:明明在写了一套toy的compiler,却骗别人说我是试试一种同步转异步的某个想法。

还是解释器吧,只需要把current continuation暴露出来,这是理解控制流的本质。LiSP第3章和eopl第5章都是讲continuation passing的interpret。本来想用scheme写,结果发现VM会把事情搞复杂,但是无VM用scheme写了没法给宿主语言用。

只好在C那边去写了。parser拿了个开源库,scheme的类型定义拿了自己以前一些老代码,吭哧吭哧一个阳光大好的周末又浪费了,活该屌丝一辈子。

代码在 https://github.com/tiancaiamao/yasfs/tree/master/value-of-k

暴露控制流没有采用callcc,callcc确实是最强大的,但是并不是最方便的。这里面提供了类似lua的几个函数,spawn,resume和yield。

这明明是个解释器嘛 ╮(╯▽╰)╭


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK