Возможно ли в Clojure вызвать тупик (или другой плохой случай) с использованием агентов? - PullRequest
3 голосов
/ 26 ноября 2011

Clojure агенты являются мощным инструментом.Поскольку действия агентам отправляются асинхронно с использованием функций «отправить» и «отправить», теоретически что-то вроде тупика не могло произойти.

Можно ли написать некоторый код Clojure (например, вызывая из какого-либо действия другое действие к другому агенту), используя агентов, у которых у нас есть некоторая проблема параллелизма - это может быть тупик, состояние гонки или что-то еще.

Ответы [ 2 ]

9 голосов
/ 26 ноября 2011

send и send-off добавляют функции в очереди для агента и немедленно возвращаются.Таким образом, из-за их асинхронного характера они не могут зайти в тупик.

Однако рабочий пул, используемый send, предназначен для вычислительной работы и, таким образом, имеет фиксированный размер пула (2 + число ядер).Если вы (неправильно) вызовете send с задачей, которая может заблокировать ввод-вывод или что-то еще, эта задача заблокирует одно из фиксированного числа потоков процессора в пуле.Если бы вы делали это одновременно с (2 + # ядрами) задачами, вы могли бы эффективно блокировать пул потоков процессора.Конечно, решение состоит в том, чтобы использовать вместо него правильный send-off.Рабочий пул, используемый send-off, неограничен.

При отправке в действии страница агентов сообщает:

Если во время выполнения функции любой другойотправления производятся (прямо или косвенно), они будут удерживаться до тех пор, пока состояние агента не будет изменено.

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

Также нет возможности для гонки данных - состояние агента должно быть неизменным Clojureданные.Агент применяет функцию изменения в посылке и атомарно заменяет состояние агента.Считыватели (через dereference или @) видят стабильное значение в какой-то момент времени жизни агента.Если вам нужна координация читателей и писателей, вы должны использовать refs .

Существует возможность условия гонки : два вызова send из разных потоковможет ли "гонка" быть помещенной в очередь агента, а также одновременно читающие могут воспринимать различные (стабильные) значения в зависимости от того, когда они читают временную шкалу агента.Однако это характер асинхронных вычислений.Если вы хотите скоординированные вычисления при чтении или записи нескольких ресурсов, вы должны использовать refs .

2 голосов
/ 26 ноября 2011

Я не уверен, возможно ли это, потому что асинхронный характер вызовов «send» существует для предотвращения подобных тупиковых ситуаций.Если бы посылка была синхронной, то было бы легко возможно, т.е. снова вызвать send в функции send для того же агента, теперь посылка застряла бы, если бы она была синхронной.

...