Я пытаюсь изучить Clojure из API и документации, доступной на сайте. Я немного неясен в отношении изменяемого хранилища в Clojure, и я хочу убедиться, что мое понимание верное. Пожалуйста, дайте мне знать, есть ли какие-то идеи, которые я ошибался.Clojure mutable типы хранения
Редактировать: Я обновляю это, когда получаю комментарии о его правильности.
Отказ от ответственности: Вся эта информация носит неофициальный характер и, возможно, не так. Не используйте этот пост для получения понимания того, как работает Clojure.
Варс всегда содержат связывающий корень и, возможно, за связывание нити. Они сопоставимы с регулярными переменными на императивных языках и не подходят для обмена информацией между потоками. (спасибо Артура Ulfeldt)
работы имеют общих места между потоками, которые поддерживают атомные операции, которые могут изменить состояние любого числа рефов в одной транзакции. Сделки совершаются при выходе синхронизации выражения (dosync) и конфликтов разрешаются автоматически с STM магической (откаты, очередь, ждем и т.д.)
Агентов являются местами, которые позволяют информацию асинхронна между потоками с минимальными затратами по отправка независимых функций действия для изменения состояния агента. Агенты немедленно возвращаются и, следовательно, не блокируются, хотя значение агента не установлено до тех пор, пока функция отправки не будет завершена.
Атомы - это места, которые можно синхронно совместно использовать между потоками. Они поддерживают безопасную манипуляцию между различными потоками.
Вот мои дружеские резюме на основе, когда использовать эти структуры:
- Варса является как обычным старым переменными в императивных языках. (избегайте, когда это возможно)
- Атомы похожи на Vars, но с безопасностью обмена нитями, которая позволяет мгновенно считывать и безопасно устанавливать. (спасибо Martin)
- Агент как Atom, но вместо того, чтобы блокировать его, он генерирует новый поток для вычисления его значения, только блокирует, если он находится в середине изменения значения, и может позволить другим потокам знать, что он завершен, назначая ,
- Refs - это общие местоположения, которые блокируются в транзакциях. Вместо того, чтобы программист решал, что происходит во время условий гонки для каждой части заблокированного кода, мы просто запускаем транзакцию и позволяем Clojure обрабатывать все условия блокировки между ссылками в этой транзакции.
Также, связанная с этим концепция - это функция future
. Для меня кажется, что будущий объект можно охарактеризовать как синхронный Агент, где невозможно получить доступ к значению до тех пор, пока вычисление не будет завершено. Он также может быть описан как неблокирующий Atom. Являются ли эти точные концепции будущего?
Вы объясняете эти поправки очень ясно, благодаря! Идея корневой привязки меня немного смущает, потому что я не вижу для нее никакого преимущества. Я предполагаю, что это по большей части техническая причина, как сохранение измененных переменных из стека, чтобы они не освобождались. – Kai