Я визуализирую порядок команд, используя временные шкалы.Давайте рассмотрим следующий код.
x++;
y++;
Итак, наши инструкции разбиты следующим образом.
Read(x) --> Increment(x) --> Write(x) --> Read(y) --> Increment(y) --> Write(y)
Для краткости давайте сократим это до следующего.
R(x) --> I(x) --> W(x) --> R(y) --> I(y) --> W(y)
Поэтому, если у нас есть 2 потока, выполняющих эти инструкции, тогда мы можем нарисовать 2 временные шкалы, например, так:
T1: R(x) --> I(x) --> W(x) --> R(y) --> I(y) --> W(y)
T2: R(x) --> I(x) --> W(x) --> R(y) --> I(y) --> W(y)
Теперь вот гигантский скачок.Когда вы рисуете возможные сроки, делайте это с точки зрения другого потока.Это важно, поскольку инструкции могут быть переупорядочены с точки зрения другого потока (с ограничениями 1 ).Таким образом, следующая диаграмма является полностью допустимой последовательностью выполнения для T1
, как видно из другого потока .
T1: R(y) --> R(x) --> I(x) --> I(y) --> W(y) --> W(x)
Теперь давайте добавим символы [
и ]
для представления блокировкиприобрести и заблокировать разблокировку соответственно.[
не может пройти мимо другого [
и не может двигаться до ]
.Аналогичные ограничения на изменение порядка применяются для символа ]
.Также важно, что ни одна инструкция не может пройти мимо [
или ]
, но они все еще могут свободно перемещаться внутри секции блокировки.Конечным результатом является то, что блокировки сериализуют выполнение инструкций (вы уже это знаете), и они в некоторой степени предотвращают переупорядочение (которое вы, возможно, не знали).-->
(интервал между инструкциями) может быть произвольно удлинен или укорочен для имитации чередования нитей.Длина задержек инструкций будет сильно зависеть от планировщика потоков, используемых механизмов синхронизации и т. Д. И обычно будет очень случайной.
Поэкспериментируйте со смещением инструкций влево и вправо по временной шкале, чтобы помочь вампредставьте, что может произойти.Создайте свои собственные символы и сокращения для замков, инструкций и задержек, чтобы помочь с визуализацией и дать подсказки о том, как далеко вы можете перемещать каждый элемент влево или вправо.
1 В действительности никакое чтение одной и той же переменной не может пройти мимо записи.Это должно быть интуитивно понятно, но не повредит формализовать это ограничение.