Нити в SBCL

Материал из wiki.lissyara.su
Перейти к: навигация, поиск

Это перевод заметки Threads in SBCL.

По некоторым причинам работа с нитями в SBCL не очевидна. Я буду использовать это сообщение в качестве сборника некоторых способов работы с нитями для начинающих в программировании мульти-потоковых программ в SBCL. Требование: SBCL должен собираться с нитями (по умолчанию, эта опция отключена). Проверить наличие поддержки нитей можно следующим способом
(not (null (member :sb-thread *features*)))

Использование

Всё что связано с нитями лежит в пакете SB-THREAD, и если Вы не хотите добавлять префиксы то Вам придётся импортировать этот пакет:
(use-package :sb-thread)

Создание нити

(make-thread (lambda () ...) :name "optional name")

Порождает новую нить, которая выполняет лямбду и возвращает нить. После вычислении лямбды нить будет тихо прервана. Вы можете ожидать завершение выполнения нити через использование JOIN-THREAD.

Список нитей

(list-all-threads)

Этим всё сказано.

Отладка нитей

Используйте RELEASE-FOREGROUND для переключения между несколькими нитями, ожидающими ввода:

CL-USER(15): (make-thread (lambda () (break)))
 
debugger invoked on a SIMPLE-CONDITION in thread #< thread RUNNING {AA9E831}>:
  break
 
#< thread RUNNING {AA9E831}>
CL-USER(16): (release-foreground)
 
Resuming thread #< thread RUNNING {A93CD49}>
 
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
 
restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE        ] Return from BREAK.
  1: [TERMINATE-THREAD] Terminate this thread (#< thread RUNNING {A93CD49}>)
 
(BREAK "break")3
0] (release-foreground)
Resuming thread #< thread "initial thread" RUNNING {A6DD551}>
CL-USER(17):

Очистка

Возможно это окажется очевидным для людей, знакомых со стеком семантики нитей:

CL-USER(25): (make-thread (lambda () (unwind-protect (break) (format t "cleanup~%"))))
 
#<thread RUNNING {AB89DB9}>
CL-USER(26):
debugger invoked on a SIMPLE-CONDITION in thread #< thread RUNNING {AB89DB9}>:
  break
(release-foreground)
Resuming thread #< thread RUNNING {AB89DB9}>
 
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
 
restarts (invokable by number or by possibly-abbreviated name):
  0: [CONTINUE        ] Return from BREAK.
  1: [TERMINATE-THREAD] Terminate this thread (#< thread RUNNING {AB89DB9}>)
 
(BREAK "break")
0]
1
Resuming thread #< thread "initial thread" RUNNING {A6DD551}>
1
CL-USER(27): cleanup
</thread>

Различные примечания

Хэш таблицы

В некоторых случаях SBCL сбрасывает блокировку с хэш таблиц, что даёт пользователю полную свободу для реализации своего уровня блокировки. По этой причине Вам нужно озаботиться защитой ваших хэш таблиц от одновременного доступа.

Модель нити

Есть две фундаментальные модели для каркаса нитей: использование родных возможностей Операционной Системы по работе с нитями или реализация своего планировщика одновременной работы. Allegro использует второй метод, в то время когда SBCL и ECL используют нити Операционной Системы.