Emacs Lisp 提供一种有限形式的并发机制,称为 线程(threads)。Emacs 单个实例中的所有线程共享同一块内存。 Emacs Lisp 中的并发为 “基本协作式(mostly cooperative)”,意味着 Emacs 仅会在明确规定的时机 在不同线程间切换执行。不过,Emacs 的线程支持在设计上已为后续支持更细粒度的并发 做好了准备,正确的程序不应依赖协作式线程。
目前,线程切换会在以下场景发生:通过 thread-yield 显式请求时、
等待键盘输入或异步进程的输出时(例如在 accept-process-output 期间),
或是在与线程相关的阻塞操作中,如互斥锁加锁或 thread-join。
Emacs Lisp 提供创建和控制线程的原语,同时也支持创建和控制互斥锁与条件变量, 这些常用于线程同步。
全局变量在所有 Emacs Lisp 线程间共享,而局部变量则不共享—动态的 let
绑定是线程局部的。每个线程还拥有各自的当前缓冲区(see 当前缓冲区)
以及各自的匹配数据(see 匹配数据)。
注意,Emacs Lisp 实现会对 let 绑定做特殊处理。
除使用 let 之外,无法复制这种变量入栈与恢复的行为。
例如,用 unwind-protect 手动实现的 let 无法让变量值
具备线程局部特性。
对于词法绑定(see Scoping 变量绑定的作用域规则),闭包在 Emacs Lisp 中 与其他对象无异,闭包中的绑定会被所有调用该闭包的线程共享。