Это не работает, потому что вещи, которые вы, по-видимому, считаете атомарными (т. е. неделимыми), на самом деле таковыми не являются.
Прямо сейчас вы, кажется, предполагаете, что как только цикл while
в одном процессе завершится, выполнение будет продолжаться, по крайней мере, на протяжении всего присваивания flag[N]
без каких-либо переключений контекста.
Это просто неправда. Для удобства разобьем каждый процесс на части A (цикл while) и B (критическая секция). Вполне возможно иметь последовательность вроде:
1A
2A
1B [for a while, then interrupted by context switch]
2B [for a while, then interrupted by context switch]
1B [resumes after context switch]
2B [resumes after context switch]
Это именно такой код, который работает в 99,9% случаев. Вы, вероятно, можете тестировать его как сумасшедший в течение нескольких месяцев подряд, и покажется, что он работает идеально — затем вы продемонстрируете его перед клиентом, он рухнет, сгорит и уничтожит все, что его окружает. Затем вы отправляете его обратно в лабораторию, и как бы они ни старались, они не могут воспроизвести проблему.
person
Jerry Coffin
schedule
14.12.2014