关于 run-at-time 异步的实现机制

elisp

#1

JavaScript 是单线程的,可以通过浏览器或者 Node.js 的运行时环境实现异步编程。JavaScript的 setTimeout 函数可以让某个 callback 定时执行。

setTimeout 为例,在 Node.js 的实现里:

  1. setTiemout(func, 1000) 在调用栈里执行 setTimeout 立即返回
  2. 随后它会把 func 放入对应任务队列(这里应该是Timer任务队列)
  3. 1s内,event loop 轮询 消息队列 获取事件消息,当消息队列没有事件时,消息队列阻塞,所以不会占用cpu时间
  4. 1s后,event loop 从消息队列获得计时结束的事件消息,从对应任务队列中取出 func 并执行

Emacs 也提供了一个定时器api,run-at-time,我发现它的 timer-list 是一个 C 变量,猜想底层是不是也是使用 event loop 的方式实现的?

参考资料:

deferred.el 也是利用 run-at-time 来实现异步的。

也有人按照 JavaScript 标准异步接口 Promise 写了对应 Emacs 的库,不过是用多进程的方式实现的。

emacs-promise


#2

硬件有定时器,通过中断通知操作系统,系统再调用应用程序的回调函数。

我猜是这样吧