Впервые появилась в W32. Синхронизация – это средство, позволяющее реализовать вытесняющую многозадачность, то есть реализовать переключение программ в любой момент времени. Синхронизация может выполняться в пользовательском режиме: критические секции и функции Interlocked.
В режиме ядра для синхронизации используются следующие объекты: события, семафоры, мьютексы.
В Windows 2000 появился новый объект – ожидающий таймер.
Cинхронизация может выполняться с помощью таких объектов ядра, как процессы, потоки, задания, файлы. Оповещение об изменениях файловой системы, CON ввод/вывод. Синхронизация используется для единоличного доступа к ресурсам и для оповещения о каких-либо событиях, например, когда необходима синхронизация – это работа с базой данных. В тот момент когда происходит запись, то другие операции должны быть заблокированы.
Пример, для оповещения событий. Процесс состоит из двух потоков.
Поток 1 считывает данные с файда, поток 2 выводит на экран. Естественно поток 2 ожидает выполнение потока 1.
Синхронизация потоков без использования
Пусть есть 2 потока. Поток 1 синхронизирует себя завершением какой-либо задачи в другом потоке, постоянно просматривая значения некоторой переменной, доступной из обоих потоков.
нет
да
Существуют проблемы.
1. Первый поток никогда не впадает в «спячку». Он тратит время процессора на проверки.
2. Булева переменная f никогда не примет значения true.
Вывод: синхронизация необходима.
Синхронизация потоков.
1. Объекты синхронизации могут находится в двух состояниях.
1) signaled – свободен
2) non-signaled – занят
2. Если состояние свободное, то работа потока разрешена, если в занятом, то запрещена. Для созда-ния объектов синхронизации используются функции типа
CreateMutex(…) (тот кто открывает, тот и закрывает, нет счётчика),
CreateSemaphore(…) (есть счётчик),
CreateEvent(…).
Они возвращают дескриптор (указатель) на созданный объект.
3. Для перехода объектов синхронизации в свободное состояние используются функции типа
ReleaseMutex(…),
ReleaseSemaphore(…),
ReleaseEvent(…).
4. Для ожидания освобождения события используются функции
WaitForSingleObject(…) – ожидает освобождение какого-либо одного объекта. В качестве пара-метров передаётся дескриптор объекта, время ожидания.
WaitForMultipleObject(…) – ожидает освобождения нескольких объектов. В качестве параметров выступают указатель на массив дескрипторов, количество ожидаемых объектов, время ожидания и тип ожидания (все объекты или хотя бы один объект).
Пример. Пусть имеется база данных, к которой по сети обращаются несколько пользователей. Для обслуживания запроса каждого пользователя создаётся отдельный поток. В созданном потоке надо организовать единоличный доступ к записям базы данных.
CreateMutex(…);
WaitForSingleObject(…);
ОС анализирует, в каком состоянии находится объект синхронизации. Если объект синхронизации находится в состоянии non-signaled, то ОС прекращает выполнение этого потока.
// Обработка базы данных.
Если объект занят, то обработка не будет происходить.
ReleaseMutex(…)
Если объект находится в свободном состоянии, то функция WaitForSingleObject(…) переводит его в занятое состояние, то есть никакой другой поток не может получить доступ к данным.