3

异步编程之 CPS

 2 years ago
source link: https://forrestsu.github.io/posts/architecture/asynchronous-programming-cps/
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

异步编程之 CPS

2018年4月20日
| 字数 1441

1 Preface

后继传递风格(continuation-passing style CPS wiki) 具体解释请阅读wiki。

CPS 最初在1970年代作为一种编程风格出现,主要用于函数式编程; 在1980年代到1990年代期间,其作为高级编程语言的编译器的一种中间表达形式开始崭露头角。

现在,CPS作为非阻塞系统(通常是分布式)的一种编程风格被再次发掘出来。

1.1 CPS in Haskell

我们使用Haskell 实现勾股定理(Pythagorean theorem) 计算斜边的长度。 传统的实现如下:

square :: Double -> Double
square x = x * x

add :: Double -> Double -> Double
add x y = x + y

pythagorean :: Double -> Double -> Double
pythagorean x y = sqrt (add (square x)  (square y))

然后我们将其改造成 CPS 的方式,如下:

add_cps :: Double -> Double -> ((Double -> r) -> r)
add_cps x y = \k -> k (add x y)

square_cps :: Double -> ((Double -> r) -> r)
square_cps x = \k -> k (square x)

pythagoras_cps :: Double -> Double -> ((Double -> r) -> r)
pythagoras_cps x y = sqrt \k ->
    square_cps x $ \x_squared ->
    square_cps y $ \y_squared ->
    add_cps x_squared y_squared $ k

main = do
    pythagoras_cps 3 4 print

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。

func funcCPS(n int, f func(int)) {
    // do something
    f(n)
    // do something
}

func main() {
    funcCPS(5, func(i int) { fmt.Printf("result: %v\n", i)})
}

2 Last

我们所掌握的自以为傲的很多知识或者技能,在可见的未来将会被更新或者淘汰, 也许是在明天,或许几年,谁知道呢。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK