关于lisp:用rust写lisp解释器2-实现一个简单的异步模型channel-thread-go

31次阅读

共计 1609 个字符,预计需要花费 5 分钟才能阅读完成。

背景

前段时间实现了一个 call-with-tcp-listener 过程(函数)

 (call-with-tcp-listener "127.0.0.1:8088" ( lambda (in) ((display  (req-read-string in))
      "HTTP/1.1 200 OK\r\n\r\n hello word"
 )))

如果是简略的返回数据还不存在问题,然而当波及到 io 的时候就会呈现阻塞的状况,最简略的解决方案就是一个申请一个线程,然而这种模型开销比拟大,所以想到了线程池,而后就实现了一个及其简略的版本

实现

应用到了 thread + channel + lambda-lep + apply 这几个过程
首先定义一个线程池
async.lisp

((define thread-qty (* (get-os-cpu-num) 2))
    (define thread-count 1)
    (define barrier (make-barrier thread-qty))
    (define channel (make-channel))
    (while (<  thread-count thread-qty)
        ((thread-run (lambda () ((channel-for-each (lambda (task) (( task)
                )) channel)
                (barrier-wait barrier)
                ;; (loop ((<- channel)))
            )))
            (set! thread-count (+ thread-count 1))))
    (define go (lambda-lep (task) ((apply (`(-> ,channel ,task)))
    )))
    (export go)
)

如何应用


((import (go) from "./async.lisp")
    (go 
        (lambda () 
            (println (current-thread-name) "hello rust-lisp!"))))

控制台会输入

thread-1 hello rust-lisp!

重构

让咱们在联合 call-with-tcp-listener 过程欠缺一下吧
首先重构一下 call-with-tcp-listener 过程使其承受 out port
main.lisp

((def handler (in out) (
        ;; 模仿 io 读取期待
        (sleep 1)
        (println (current-thread-name))
        (display  (req-read-string in))
        (write-string "HTTP/1.1 200 OK\r\n\r\n hello word" out)
    ))
    (call-with-tcp-listener "127.0.0.1:8088" ( lambda (in out) (( handler in out)
    ))))

而后应用 go 过程实现工作提交
main.lisp

((load "./lib.lisp")
    (import (go) from "./async.lisp")
    (def handler (in out) (
        ;; 模仿 io 读取期待
        (sleep 1)
        (println (current-thread-name))
        (display  (req-read-string in))
        (write-string "HTTP/1.1 200 OK\r\n\r\n hello word" out)
    ))
    (call-with-tcp-listener "127.0.0.1:8088" ( lambda (in out) ((go (lambda () (handler in out)))
    ))))

工作提交之后, 上面这段代码会从 channel 中读取到最新提交的 task (过程) 而后执行。

(channel-for-each (lambda (task) ((task)
                )) channel)

运行后拜访 控制台打印如下

thread1
GET / HTTP/1.0
Host: 127.0.0.1:8088
User-Agent: ApacheBench/2.3
Accept: */*

async.lisp 源码

正文完
 0