40 Потоков

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, а привязки в замыкании разделяются всеми потоками, вызывающими это замыкание.