Я помню, что в курсе, который я выбрал в колледже, одним из моих любимых примеров состояния гонки был случай, когда простой метод main()
запускал два потока, один из которых увеличивал общую (глобальную) переменную на единицу,другие уменьшают это.Псевдокод:
static int i = 10;
main() {
new Thread(thread_run1).start();
new Thread(thread_run2).start();
waitForThreads();
print("The value of i: " + i);
}
thread_run1 {
i++;
}
thread_run2 {
i--;
}
Затем профессор спросил, каково значение i
после миллиона миллиардов пробежек.(Если это вообще что-то отличное от 10). Учащиеся, незнакомые с многопоточными системами, отвечали, что в 100% случаев оператор print()
всегда будет сообщать i
как 10.
Это было вфакт неверный, так как наш профессор продемонстрировал, что каждое утверждение приращения / убывания было фактически скомпилировано (в сборку) как 3 утверждения:
1: move value of 'i' into register x
2: add 1 to value in register x
3: move value of register x into 'i'
Таким образом, значение i
может быть 9, 10 или 11.(Я не буду вдаваться в подробности.)
Мой вопрос:
Насколько я понимаю, набор физических регистров зависит от процессора.При работе с двухпроцессорными машинами (обратите внимание на разницу между двухъядерным и двухпроцессорным процессами), имеет ли каждый ЦП свой набор физических регистров? Я предположил, что ответ - да.
На однопроцессорной (многопоточной) машине переключение контекста позволяет каждому потоку иметь свой собственный виртуальный набор регистров.Поскольку на двухпроцессорной машине имеется два физических набора регистров, это не может привести к еще большему потенциалу для состязания, так как вы можете буквально иметь два потока, работающих одновременно, в отличие от «виртуальной» одновременной работы на одном компьютере.Процессор?(Виртуальная одновременная операция в связи с тем, что состояния регистров сохраняются / восстанавливаются при каждом переключении контекста.)
Если быть более точным - если вы выполняли это на 8-процессорной машине, каждый ЦП имел один потокусловия гонки устранены?Если вы расширите этот пример для использования 8 потоков на двухпроцессорной машине, каждый из которых имеет 4 ядра, увеличится или уменьшится потенциал условий гонки? Как операционная система предотвращает одновременное выполнение step 3
инструкций по сборке на двух разных процессорах?