Содержание материала

Mutex (Mutually Exclusive)

Мутекс это объект синхронизации, который находится в сигнальном состоянии только тогда, когда он не принадлежит ни одному из процессов. Как только хотя бы один процесс запрашивает владение мутексом, он переходит в несигнальное состояние и остается в нем до тех пор, пока не будет освобожден владельцем. Такое поведение позволяет использовать мутексы для синхронизации совместного доступа нескольких процессов к разделяемому ресурсу. Для создания мутекса используется функция:

 

function CreateMutex(

lpMutexAttributes: PSecurityAttributes;  // Адрес структуры

                                          // TSecurityAttributes

bInitialOwner: BOOL;  // Задает, будет ли процесс владеть

                       // мутексом сразу после создания

lpName: PChar         // Имя мутекса

): THandle; stdcall;

 

Функция возвращает идентификатор созданного объекта, либо 0. Если мутекс с заданным именем уже был создан, возвращается его идентификатор. В этом случае функция GetLastError вернет код ошибки ERROR_ALREDY_EXISTS. Имя не должно совпадать с именем уже существующего объекта типов Semaphore, Event, Job, Waitable Timer или FileMapping

Если неизвестно, существует ли уже мутекс с таким именем, программа не должна запрашивать владение объектом при создании (т.е. должна передать в качестве bInitialOwner значение FALSE).

Если мутекс уже существует, приложение может получить его идентификатор функцией

 

function OpenMutex(

dwDesiredAccess: DWORD;  // Задает права доступа к объекту

bInheritHandle: BOOL;    // Задает, может ли объект наследоваться

                          // дочерними процессами

lpName: PChar            // Имя объекта

): THandle; stdcall;

 

Параметр dwDesiredAccess может принимать одно из следующих значений

MUTEX_ALL_ACCESS        Приложение получает полный доступ к объекту        

SYNCHRONIZE        Только для Windows NT приложение может использовать объект только в функциях ожидания и функции ReleaseMutex        

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

function ReleaseMutex(hMutex: THandle): BOOL; stdcall;

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

Code:

var

Mutex: THandle;

 

// При инициализации программы

Mutex := CreateMutex(NIL, FALSE, 'UniqueMutexName');

if Mutex = 0 then

RaiseLastWin32Error;

 

...

// Доступ к ресурсу

WaitForSingleObject(Mutex, INFINITE);

try

// Доступ к ресурсу, захват мутекса гарантирует,

// что остальные процессы пытающиеся получить доступ

// будут остановлены на функции WaitForSingleObject

...

finally

// Работа с ресурсом окончена, освобождаем его

// для остальных процессов

ReleaseMutex(Mutex);

end;

 

...

// При завершении программы

CloseHandle(Mutex);

 

 

 

Подобный код удобно инкапсулировать в класс, который создает защищенный ресурс, мутекс, имеет свойства и методы для оперирования ресурсом, защищая их при помощи функций синхронизации.

Разумеется, если работа с ресурсом может потребовать значительного времени, то необходимо либо использовать функцию MsgWaitForSingleObject, либо вызывать WaitForSingleObject в цикле с нулевым периодом ожидания, проверяя код возврата. В противном случае Ваше приложение окажется замороженным. Всегда защищайте захват-освобождение объекта синхронизации при помощи блока try ... finally, иначе ошибка во время работы с ресурсом приведет к блокированию работы всех процессов, ожидающих его освобождения.

Добавить комментарий

Не использовать не нормативную лексику.

Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.

ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!


Защитный код
Обновить