Подумайте о состоянии гонки, используя традиционный пример.Допустим, у вас и вашего друга есть банкоматные карточки на один и тот же банковский счет.Теперь предположим, что на счете 100 долларов.Подумайте, что происходит, когда вы пытаетесь снять 10 долларов, а ваш друг пытается снять 50 долларов в одно и то же время.
Подумайте, что должно произойти.Банкомат должен принять ваши данные, прочитать, что в данный момент находится в вашей учетной записи, а затем изменить сумму.Обратите внимание, что в терминах программирования оператор присваивания является многоэтапным процессом.
Итак, пометьте обе ваши транзакции T1 (вы снимаете 10 долларов США) и T2 (ваш друг снимает 50 долларов США).Теперь числа внизу слева обозначают временные шаги.
T1 T2
---------------- ------------------------
1. Read Acct ($100)
2. Read Acct ($100)
3. Write New Amt ($90)
4. Write New Amt ($50)
5. End
6. End
После завершения обеих транзакций, используя эту временную шкалу, которая возможна, если вы не используете какой-либо механизм блокировки, на счете будет 50 долларов.Это на 10 долларов больше, чем должно быть (ваша транзакция потеряна навсегда, но у вас все еще есть деньги).
Это условие гонки, называемое гонкой.Вы хотите, чтобы транзакция была сериализуемой , то есть независимо от того, как вы чередуете выполнение отдельных команд, конечный результат будет точно таким же, как некоторое последовательное расписание (т.е.вы запускаете их один за другим без чередования) одних и тех же транзакций.Решение, опять же, состоит в том, чтобы ввести блокировку;однако неправильная блокировка может привести к мертвой блокировке.
тупиковая ситуация возникает при конфликте общего ресурса.Это что-то вроде Catch-22.
T1 T2
------- --------
1. Lock(x)
2. Lock(y)
3. Write x=1
4. Write y=19
5. Lock(y)
6. Write y=x+1
7. Lock(x)
8. Write x=y+2
9. Unlock(x)
10. Unlock(x)
11. Unlock(y)
12. Unlock(y)
Вы видите, что тупик возникает в момент 7, потому что T2 пытается получить блокировку на x
, но T1 уже удерживает блокировку на x
, ноон ожидает блокировки для y
, которую удерживает T2.
Это плохо.Вы можете превратить эту диаграмму в граф зависимостей, и вы увидите, что существует цикл.Проблема здесь в том, что x и y - это ресурсы, которые могут быть изменены вместе.
Один из способов предотвратить проблему взаимоблокировки такого рода с несколькими объектами (ресурсами) блокировки - ввести порядок.В предыдущем примере вы видите, что T1 заблокирован x
, а затем y
, но T2 заблокирован y
, а затем x
.Если обе транзакции придерживаются здесь некоторого правила заказа, которое гласит «x
, всегда должно быть заблокировано до y
», то эта проблема не возникнет.(Вы можете изменить предыдущий пример, помня об этом правиле, и увидите, что тупик не возникает).
Это тривиальные примеры, и на самом деле я просто использовал примеры, которые вы, возможно, уже видели, если вы взяли какой-либо видСтуденческий курс по этому вопросу.В действительности, решение проблем взаимоблокировки может быть намного сложнее, чем это, потому что вы, как правило, имеете больше, чем пару ресурсов и несколько транзакций, взаимодействующих.
Надеюсь, это немного поможет.Как всегда, используйте Википедию в качестве отправной точки для концепций CS:
http://en.wikipedia.org/wiki/Deadlock
http://en.wikipedia.org/wiki/Race_condition