Думайте нелинейно. Вы указали три проблемы в определении Silberchatz, предоставленном для реализации функции testAndSet () :
(1) вы правильно указали, что target установлен на TRUE безоговорочно, и поняли (ошибочно), что это проблема.
(2) Чтобы решить проблему в (1) (которая отсутствует), вы предложили протестировать target , прежде чем установить его в значение TRUE.
(3) Наконец, вы продемонстрировали свои опасения по поводу того факта, что результат установлен в FALSE также безоговорочно блоком, который реализует Взаимное исключение (это на самом деле не происходит).
Я постараюсь прояснить эти вопросы. Первоначально обратите внимание, что первое, что делает функция TestAndSet () , это скопировать значение target в rv и только потом target устанавливается безоговорочно на TRUE. Теперь выгода: если target изначально была FALSE, TestAndSet () устанавливает target в TRUE и возвращает FALSE, поэтому процесс может войти в критическую секцию. В случае, если исходное значение target было TRUE, оно все равно устанавливается в TRUE (что не причиняет вреда), а TestAndSet () возвращает TRUE, поэтому процесс НЕ может войти в критическую область. Таким образом, установка target безусловно на TRUE не является проблемой, и проблема (1) оказывается несуществующей.
Что касается проблемы (2), то, как показано выше, безвредно безоговорочно установить для target значение TRUE, нет необходимости предварительно проверять его значение.
Проблема (3) также не существует, потому что результат на самом деле не установлен безусловно на ЛОЖЬ. Я имею в виду, что это так, но только ПОСЛЕ критической области был обработан процессом; т.е. когда взаимное исключение больше не требуется. Процесс ДОЛЖЕН установить target в FALSE, как только он покинет критическую секцию (он не должен блокировать какие-либо другие процессы после выхода из критической секции). Обязательно снимите блокировку после обработки критической секции!