Как работает поездка? - PullRequest
       3

Как работает поездка?

1 голос
/ 14 ноября 2010

Как на самом деле работает коммутирует.(коммутировать IDENTITY FUNCTION и значения)

Документация Clojure гласит:

Использование: (commute ref fun & args)

Должен вызываться в транзакции.Устанавливает значение in-транзакции ref равным:

(применяет забавные аргументы in -action-value-of-ref) и возвращает значение in-транзакции ref.

Вточка фиксации транзакции устанавливает значение ref следующим образом:

(применяет забавные аргументы "последнее добавленное значение-ref-аргумента")

Таким образом, форма коммутированиявыполняется в два этапа.

является ли второй этап атомарным? (примените забавные аргументы "последнее добавленное значение-из-ref")

, если нет, что произойдет в этом примере: 2 потока(T1 и T2).

Оба будут увеличивать (коммутативная функция) один и тот же идентификатор.

 IDENTITY: (def i (ref 0 ) 
        (dosync (commute inc i ) )

T1 на первом шаге вызова на коммутацию inc с ref i = 0 (в транзакциизначение = 1)

остановка T1

T2 на первом шаге коммутируемого вызова inc с ref i = 0 (в значении транзакции = 1)

остановка T2

T1 во втором шаге снова вызывает inc с последним значением коммита i = 0, функция inc возвращается, но перед обновлением ref (i) T1 останавливается

T2 во втором шаге снова вызовите inc с последним значением фиксации i = 0 и обновите ссылку

T1 запустите снова и обновите ссылку с возвращенным значением inc = 1

Это проблема состояния гонки?Как избежать этого?если вторая фаза будет атомарной, этого не произойдет.

Заранее спасибо

ОБНОВЛЕНИЕ: если я правильно понимаю, последняя фаза операций коммутации (точка фиксации) синхронизирована "LOCK commuteвесело разблокировать ** "?

1 Ответ

5 голосов
/ 15 ноября 2010

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

InВ вашем примере потоки T1 и T2 выполняют свои транзакции одновременно, причем i ссылается на 0. Они оба (в том числе i) через коммутируют, и поэтому оба видят i = 1 во время своих транзакций.Однако, когда они будут готовы к фиксации, функция, указанная в commute (inc), будет применена к ссылке с использованием значения последнее добавленное .Таким образом, если T1 фиксирует сначала, i = 1, то T2 фиксирует, и i = 2.В ответ на ваш вопрос, эти коммиты действительно атомарны, и поэтому условия гонки невозможны.

Я цитирую документацию для коммутирования ниже:

В точке фиксации транзакции задаетзначение ref должно быть:

(apply fun most-recently-committed-value-of-ref args)

Таким образом, веселье должно быть коммутативным, или, в противном случае, вы должны принять поведение «последний в выигрыше».

Бит «последний-один-в-выигрыше» предупреждает вас, что если применяемая вами функция не коммутативна - умножение матриц приходит на ум - тогда фактически гонка возможно возможно.То есть транзакция, которая фиксирует первый, будет иметь свою функцию, примененную к «исходному» значению ref, а следующая транзакция, которая будет зафиксирована, будет применена к обновленному состоянию.Однако приложения функций все еще применяются атомарно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...