Architecture Net



         

Потоки - часть 6


К сожалению, оба клиента добиваются резервирования последнего (единственного) номера на 13 декабря! Обратите внимание на то, как один из потоков выполняет метод Reserve (Резерв) и находит, что номер доступен прежде, чем прекратит свою работу. Затем другой поток выполняет Reserve (Резерв) и также обнаруживает свободный номер прежде, чем закончится отведенный для него промежуток времени. Потом оба потока заказывают тот же самый номер гостиницы.

Операционные системы предоставляют средства синхронизации взаимодействия нескольких потоков и процессов, получающих доступ к совместно используемым ресурсам. Каркас .NET Framework предусматривает несколько механизмов предотвращения конфликтов между потоками.


Каждый объект в каркасе .NET Framework может использоваться в качестве синхронизирующей секции кода (критической секции). В пределах такой секции одновременно может выполняться только один поток. Если один поток уже выполняется внутри такой синхронизирующей секции кода, любые другие потоки, пытающиеся получить доступ к данной секции, блокируются (и ждут) до тех пор, пока выполняющийся поток не покинет эту секцию кода.

Синхронизация с помощью мониторов

Класс System: :Threading: :Monitor (Система::Организация поточной об-работки::Монитор) позволяет потокам синхронизировать доступ к объектам, чтобы избежать нарушения целостности данных и неопределенного поведения вследствие соперничества между потоками. Шаг 2 из примера Threading (Организация поточной обработки) демонстрирует использование класса Monitor (Монитор) с указателем this экземпляра HotelBroker.

ReservationResult *Reserve(Reservation *res) // Резервирование


{
Console::WriteLine(
"Thread {0} trying to enter Broker::Reserve",
// "Поток {0} пытается войти в Брокер::Резерв",


Thread::CurrentThread-> // Поток
GetHashCode() .ToString ()); Monitor::Enter(this); // Монитор::Войти


. . . (спорный код потока здесь) Monitor::Exit(this); // Выход


return result; // результат
}

Потоку, который первым вызовет метод Monitor: : Enter (this), будет разрешено выполнить метод Reserve (Резерв), потому что он овладеет замком метода Monitor (Монитор) с помощью указателя this. Потоки, пробующие выполнить те же действия, должны будут ожидать, пока первый поток не разблокирует замок с помощью метода Monitor: :Exit (this). После этого и другие потоки смогут вызвать Monitor::Enter(this) и овладеть замком.




Содержание  Назад  Вперед