#concurrency #clojure
Вопрос:
Как на самом деле работают поездки на работу. (ФУНКЦИЯ и значения КОММУТАЦИОННОЙ ИДЕНТИЧНОСТИ)
в документации Clojure говорится:
Использование: (ссылки на поездки и аргументы)
Должно быть вызвано в транзакции. Устанавливает значение 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
Это проблема с условиями гонки ? как избежать этого ? если вторая фаза будет атомной, этого не произойдет.
Заранее спасибо
ОБНОВЛЕНИЕ: если я правильно понимаю, последняя фаза операций коммутации ( точка фиксации ) синхронизирована»БЛОКИРОВКА коммутации и РАЗБЛОКИРОВКА**» ?
Ответ №1:
Ключ состоит в том, чтобы понять, что значение ссылки в транзакции (в результате перехода) на самом деле может отличаться от значения, которое в конечном итоге записывается в ссылку в точке фиксации.
В вашем примере потоки T1 и T2 выполняют свои транзакции одновременно, причем i ссылается на 0. Они оба (включая i) совершают поездки на работу и, следовательно, оба видят i=1 во время своих транзакций. Однако, когда они будут готовы к фиксации, функция, указанная в коммутации (inc), будет применена к ссылке, используя последнее зафиксированное значение. Поэтому, если T1 совершает первый, i=1, затем T2 совершает, и i=2. В ответ на ваш вопрос, эти коммиты действительно являются атомарными, и поэтому никакие условия гонки невозможны.
Я цитирую документацию для поездок на работу ниже:
В точке фиксации транзакции устанавливает значение ref равным:
(apply fun most-recently-committed-value-of-ref args)
Таким образом, веселье должно быть коммутативным, или, в противном случае, вы должны принять поведение «последний в выигрыше».
«Последний-один-В-выигрыши» бит предупреждает Вас, что если функция вы претендуете это не коммутативные — умножение матриц приходит на ум, — то на самом деле гонки — это возможно. И. Е., сделки, которые совершает первый будет иметь свою функцию в случае «оригинальное» значение ref, и следующей транзакции для совершения будет иметь свои функции, применяемых в обновленное состояние. Однако приложения функций по-прежнему применяются атомарно.
Комментарии:
1. Милая Микаэль. итак, если я правильно понимаю, последняя фаза коммутационных операций ( точка фиксации ) синхронизирована» БЛОКИРОВКА коммутации»?