2015-02-01 3 views
3

Привет, я читал книгу радость clojure, а в разделе о STM у них есть изображение из двух транзакций, где A изначально извлекает одно и то же значение из ref как B, а затем обе транзакции A и B выполняет их вычисления, но A заканчивается первым и делает фиксацию переменной и, следовательно, B должен повторить попытку.Состояние гонки в Clojure stm?

Но то, о чем я размышляю, это то, что если бы Б повторил с фиксацией А. И если это так, то что, если это где наоборот? Тогда окончательное значение будет существенно отличаться.

Это, кажется, просто опасно, что вас упускают из виду, и я считаю, что не понимаю его полностью. Пожалуйста, помогите мне распутать это.

ответ

6

Давайте посмотрим на пример:

(defn test-trans [] 
    (let [x (ref 1) 
     t-inC#(dosync (alter x inc)) 
     t-mul #(dosync (alter x (partial * 2))) 
     fns (flatten (repeat 10 [t-mul t-inc]))] 
    (last (pmap (fn [f] (f)) fns)) 
    @x)) 

Здесь мы имеем 2 транзакционные функции - увеличение x на 1 и умножить x на 2. Мы применяем 20 таких функций (10 каждого вида) параллельно и наблюдать конечное значение от ref. Действительно, результаты для каждого прогона различны:

=> (test-trans) 
2418 
=> (test-trans) 
2380 
=> (test-trans) 
1804 
=> (test-trans) 
4210 

На самом деле это правильное поведение. STM гарантирует, что код будет выполняться без блокировок, а изменения применяются атомарно (их нельзя применять только частично). Однако это не гарантирует, что мы получим тот же результат для разных порядков транзакций.

Clojure предлагает отличные инструменты параллельного программирования, которые упрощают запись правильного кода. Но избежать такого рода условий гонки является обязанностью разработчика (на самом деле, такие случаи являются явным признаком плохого проектирования системы).

Другой пример из SQL:

DELETE FROM tbl WHERE col=1 
UPDATE tbl SET col=2 WHERE col=1 

Если эти запросы выполняются параллельно, то независимо от того, какой уровень изоляции будет использоваться для операций - результат будет зависеть от порядка.

+0

Спасибо. Очень информативно. –

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