异步编程之 CPS
1 Preface
后继传递风格(continuation-passing style CPS wiki) 具体解释请阅读wiki。
CPS 最初在1970年代作为一种编程风格出现,主要用于函数式编程; 在1980年代到1990年代期间,其作为高级编程语言的编译器的一种中间表达形式开始崭露头角。
现在,CPS作为非阻塞系统(通常是分布式)的一种编程风格被再次发掘出来。
1.1 CPS in Haskell
我们使用Haskell 实现勾股定理(Pythagorean theorem) 计算斜边的长度。 传统的实现如下:
|
|
然后我们将其改造成 CPS 的方式,如下:
|
|
1.2 CPS用于非阻塞编程
Node.js 是用于JavaScript的高性能服务器端平台,其中禁止了阻塞过程。
因为NodeJs 底层是采用 libuv 做的支撑;
libuv 是一个纯 C 语言实现的 Reactor 库, 里面大量使用 CPS 。
优点:
我们可以很方便的将 callback 注册到 event_loop里面,当事件触发时,执行我们的callback。
也就是说,我们可以拿他来做事件驱动编程,异步并且高效。
由于是单线程,所有我们也可以减少lock 的使用。
提了这么多优点,当然也是有缺点的:
1 在callback 里面,我们不能使用有阻塞的逻辑(比如sleep, 同步读写文件等),否则后续的所有的 callback 的执行都会被推迟。
2 另一个就是:我们基于CPS 模式做了大量CPS, 当调用层级太深,会增加开发的理解和维护成本。
1.3 CPS in Go
我们写了一个例子:把一个匿名 func 作为参数,传入其他func 里面去执行;
我们也可以在这个匿名 func 外面再包装一层,形成一个新的匿名func;这样可以实现更复杂的CPS。
|
|
2 Last
我们所掌握的自以为傲的很多知识或者技能,在可见的未来将会被更新或者淘汰, 也许是在明天,或许几年,谁知道呢。