Это представлено как решение для sleeping barber problem. (Приписывается CGrand, но я нашел ссылку here)Есть ли ошибка в этом решении clojure для спального парикмахера?
Мне любопытно о dosync
блока в enter-the-shop
. Я понимаю, что это транзакция, и поэтому empty-seats
останется постоянным из-за STM. Однако, существует ли вероятность того, что send-off
будет вызываться несколько раз, если транзакция будет повторена? Если нет, то почему, и если да, то как это решить?
UPDATE
Хотя принятый ответ по-прежнему верна, одна вещь, которую я только что заметил, что есть оптимизация, которая может быть - нет никаких оснований называть send-off
внутри транзакции. Он может быть отправлен после, как только вы возвращаемое значение сделки, следующим образом:
(if (dosync
(when (pos? @empty-seats)
(alter empty-seats dec)))
(send-off barber cut-hair n)
(debug "(s) turning away customer" n))
Интересно, я понял это, работая на Haskell equivalent, который заставляет вас использовать различные типы для «агентов» в STM и вне СТМ. Исходное решение выше не будет компилироваться, поскольку они должны быть либо как в транзакции, либо вне любой транзакции. (Моя первая реакция заключалась в том, чтобы поместить их в транзакцию, пока я не понял, что в этом нет необходимости, и оба они могут быть извлечены).
Я думаю, что модифицированная транзакция должна быть превосходной, поскольку она быстрее закрывает транзакцию, удаляет переменную из транзакции, и мне кажется, что ее легче читать (нет необходимости даже задаваться вопросом о возможности ее отправки дважды - , что на самом деле делает весь этот вопрос спорным). Тем не менее, я оставлю вопрос в любом случае кому-либо еще, кто должен знать, как взаимодействуют STM и агенты.
Значит ли это, что транзакция остается открытой на всю продолжительность стрижки? И это означает, что 'dosync' в' cut-hair' не нужен? –
Если транзакция остается открытой все это время, разве это не означает, что произойдет огромное количество транзакций с ошибкой/повторным запуском? –
@DaxFohl Действие 'send-off' будет запускаться * после * транзакции, а не во время этого. 'cut-hair' будет добавляться только в очередь агента после совершения транзакции, а затем в какой-то неопределенной точке в будущем' cut-hair' будет выполняться агентом. 'Dosync' в' cut-hair' необходим, потому что 'cut-hair' не запускается в транзакции. – mange