Emacs Lisp предоставляет ограниченную форму параллелизма, называемую потоками. Все потоки в данном экземпляре Emacs используют одну и ту же память. Параллелизм в Emacs Lisp является «в основном кооперативным», что означает, что Emacs будет переключать выполнение между потоками только в четко определенных моментах. Однако поддержка потоков Emacs была разработана таким образом, чтобы в дальнейшем позволить более гранулированный параллелизм, и правильные программы не должны полагаться на кооперативную многопоточность.
В настоящее время переключение потоков происходит по явному запросу через
thread-yield, при ожидании ввода с клавиатуры или вывода процесса
от асинхронных процессов (например, во время
accept-process-output), или во время блокирующих операций,
относящихся к потокам, таких как блокировка мьютекса или thread-join.
Emacs Lisp предоставляет примитивы для создания и управления потоками, а также для создания и управления мьютексами и переменными состояния, полезными для синхронизации потоков.
Хотя глобальные переменные разделяются всеми потоками Emacs Lisp, локальные
переменные не разделяются — привязка динамического let является
локальной. Каждый поток также имеет свой собственный текущий буфер (см.
Текущий буфер) и свои собственные данные
сопоставления (см. Данные сопоставления).
Обратите внимание, что привязки let обрабатываются
особым образом реализацией Emacs Lisp. Нет способа дублировать это поведение
размотки и перемотки, кроме как с помощью let. Например,
ручная реализация let, написанная с использованием
unwind-protect, не может обеспечить, чтобы значения переменных
были специфичными для потока.
В случае лексических привязок (см. Правила области видимости привязок переменных) замыкание является объектом, как и любой другой в Emacs Lisp, а привязки в замыкании разделяются всеми потоками, вызывающими это замыкание.