2010-11-14 2 views
1

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

Документация Clojure говорит:

Использование: (коммутируют исх весело & арг)

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

(примените fun in-transaction-value-of-ref args) и возвращает значение in-transaction ref.

На момент совершения сделки, устанавливает значение рефа быть:

(применять удовольствие наиболее недавно совершенной стоимость, из-рефа арга)

Так форма коесть выполняется в две фазы.

является второй фазой атомным (применяется забава наиболее недавно совершенная стоимость, из-рефа арга)

, если нет, то что произойдет в этом примере: 2 Темы (Т1 и Т2).

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

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

Т1 в первом шаге вкл коммутируют вызова с исх = 0 (в стоимости сделки = 1)

Т1 остановки

Т2 в первой стадии вкл коммутируют вызова с исх = 0 (в стоимость сделки = 1)

Т2 остановки

T1 на втором этапе вызова снова вкл с недавним фиксации значения I = 0, возвращение функции вкл, но прежде, чем U бновить арбитр (я) Т1 остановки

Т2 на второй стадии вызова снова вкл с недавним фиксации значения I = 0 и обновление эталонного

T1 начать снова и обновить ссылку с ИНК возвращаемое значение = 1

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

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

UPDATE: , если я правильно понимаю последний этап операций коммутируют (точка фиксации) синхронизировано «ЗАМОК коммутирует прикольные РАЗБЛОКИРОВАТЬ **»?

ответ

5

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

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

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

На фиксации точки сделки, устанавливает значение реф быть:

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

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

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

+1

Nice Michaelle. поэтому, если я правильно понимаю, что последняя фаза коммутируемых операций (точка фиксации) синхронизируется «LOCK commute fun UNLOK»? – CHAPa

Смежные вопросы