背景
前段时间实现了一个 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)
运行后拜访 控制台打印如下
thread1GET / HTTP/1.0Host: 127.0.0.1:8088User-Agent: ApacheBench/2.3Accept: */*
async.lisp 源码