Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Освоение среды операционной системы Microsoft W...doc
Скачиваний:
57
Добавлен:
09.11.2019
Размер:
6.83 Mб
Скачать

5.2.2. Синхронизация потоков

Многопоточный режим работы открывает новые возможности для программистов, однако за эти возможности приходится расплачиваться усложнением процесса разработки и отладки приложений. Основная трудность, с которой сталкиваются программисты, никогда не создававшие ранее многопоточные приложения, это синхронизация одновременно работающих потоков. Для чего и когда она нужна?

Однопоточная программа (например, программа MS-DOS) при запуске получает в монопольное распоряжение все ресурсы компьютера. Так как в однопоточной системе существует только один процесс, он использует эти ресурсы в той последовательности, которая соответствует логике работы программы. Процессы и потоки, работающие одновременно в многопоточной системе, могут пытаться обращаться одновременно к одним и тем же ресурсам, что может привести к неправильной работе приложений. Поясним это на простом примере.

Пусть мы создаем программу, выполняющую операции с банковским счетом. Операция снятия некоторой суммы денег со счета может происходить в следующей последовательности:

    • на первом шаге проверяется общая сумма денег, которая хранится на счете;

    • если общая сумма равна или превышает размер снимаемой суммы денег, общая сумма уменьшается на необходимую величину;

    • значение остатка записывается на текущий счет.

Если операция уменьшения текущего счета выполняется в однопоточной системе, то никаких проблем не возникнет. Однако представим себе, что два процесса пытаются одновременно выполнить только что описанную операцию с одним и тем же счетом. Пусть при этом на счету находится 5 млн. рублей, а оба процесса пытаются снять с него по 3 млн. рублей.

Допустим, события разворачиваются следующим образом:

    • первый процесс проверяет состояние текущего счета и убеждается, что на нем хранится 5 млн. рублей;

    • второй процесс проверяет состояние текущего счета и также убеждается, что на нем хранится 5 млн. рублей;

    • первый процесс уменьшает счет на 3 млн. рублей и записывает остаток (2 млн. рублей) на текущий счет;

    • второй процесс выполняет ту же самую операцию, так как после проверки считает, что на счету по-прежнему хранится 5 млн. рублей.

В результате получилось, что со счета, на котором находилось 5 млн. рублей, было снято 6 млн. рублей, и при этом там осталось еще 2 млн. рублей. Итого, банку нанесен ущерб в 3 млн. рублей.

Как же составить программу уменьшения счета, чтобы она не позволяла совершать подобные ошибки? На время выполнения операций над счетом одним процессом необходимо запретить доступ к этому счету со стороны других процессов. В этом случае сценарий работы программы должен быть следующим:

    • процесс блокирует счет для выполнения операций другими процессами, получая его в монопольное владение;

    • процесс проводит процедуру уменьшения счета и записывает на текущий счет новое значение остатка;

    • процесс разблокирует счет, разрешая другим процессам выполнение операций.

Когда первый процесс блокирует счет, тот становится недоступен другим процессам. Если второй процесс также попытается заблокировать этот же счет, он будет переведен в состояние ожидания. Когда первый процесс уменьшит счет и на нем останется 2 млн. долларов, второй процесс будет разблокирован. Он проверит остаток, убедится, что сумма недостаточна и не будет проводить операцию.

Таким образом, в многопоточной среде необходима синхронизация потоков при обращении к критическим ресурсам. Если над такими ресурсами будут выполняться операции в неправильной последовательности, это приведет к возникновению трудно обнаруживаемых ошибок.