2013-05-27 1 views
4

Это представлено как решение для sleeping barber problem. (Приписывается CGrand, но я нашел ссылку here)Есть ли ошибка в этом решении clojure для спального парикмахера?

yanked from cgrand

Мне любопытно о 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 и агенты.

ответ

5

Цитируя clojure.org page on agents:

Агенты интегрированы с STM - любые донесения, сделанные в сделке проводятся до тех пор, пока не зафиксируется, и отбрасываются, если он повторен или прервана.

Таким образом, send-off будет запускаться только один раз, когда (/ if) транзакция STM будет успешно совершена.

+0

Значит ли это, что транзакция остается открытой на всю продолжительность стрижки? И это означает, что 'dosync' в' cut-hair' не нужен? –

+0

Если транзакция остается открытой все это время, разве это не означает, что произойдет огромное количество транзакций с ошибкой/повторным запуском? –

+0

@DaxFohl Действие 'send-off' будет запускаться * после * транзакции, а не во время этого. 'cut-hair' будет добавляться только в очередь агента после совершения транзакции, а затем в какой-то неопределенной точке в будущем' cut-hair' будет выполняться агентом. 'Dosync' в' cut-hair' необходим, потому что 'cut-hair' не запускается в транзакции. – mange