Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Старое / АОПИ. Глава 2. Конспекты (02_04_19).rtf
Скачиваний:
65
Добавлен:
10.09.2019
Размер:
363.46 Кб
Скачать

If (!ReleaseSemaphore( ghSemaphore, 1, null)) /// Если ошибка

printf("ReleaseSemaphore ошибка: %d\n", GetLastError());

break;

/// Семафор не был сигнализирован, поэтому произошел тайм-аут.

case WAIT_TIMEOUT: /// Время ожидания истекло

printf("Поток %d: время ожидания истекло\n", GetCurrentThreadId());

break;

}

}

return TRUE;

}

§4. Синхронизация задач с помощью объектов ядра «мьютекс» (Mutex).

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

Мьютекс содержит счетчик числа пользователей, счетчик рекурсий и идентификатор потока-владельца.

Идентификатор потока определяет, какой поток захватил мьютекс. Счетчик рекурсий определяет, сколько раз он это сделал.

Если идентификатор потока равен 0, то мьютекс находится в сигнальном состоянии и не захвачен ни одним потоком. Если идентификатор потока не равен 0, то мьютекс захвачен одним потоком и находится в несигнальном состоянии.

Эти объекты весьма похожи на критические секции — за исключением того, что с их помощью можно синхронизировать доступ к данным со стороны нескольких процессов.

Функция создания мьютекса

HANDLE CreateMutex(

IN LPSECURITY_ATTRIBUTES lpMutexAttr,

IN BOOL bInitialOwner,

IN LPCSTR lpName

);

Краткое описание.

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

Параметры и описание:

(1) lpMutexAttr определяет указатель на структуру SECURITY_ATTRIBUTES. Если этот параметр равен NULL, дескриптор не может наследоваться дочерними процессами. Член этой структуры lpSecurityDescriptor определяет дескриптор безопасности для нового мьютекса. Если lpMutexAttr имеет значение NULL, мьютекс получает дескриптор безопасности по умолчанию.

(2) bInitialOwner определяет начальное состояние мьютекса. TRUE — несигнальное состояние (идентификатор потока-владельца в мьютексе приравнивается идентификатору вызывающего потока; счетчик рекурсии равен единице; идентификатор потока равен идентификатору вызвавшего потока). FALSE — сигнальное состояние (мьютекс не принадлежит ни одному из потоков, находится в свободном состоянии; счетчик рекурсии равен нулю; идентификатор потока равен нулю).

(3) lpName определяет имя мьютекса.

Возвращаемое значение:

Если функция завершается успешно, возвращаемое значение является дескриптором созданного объекта мьютекса, иначе возвращаемое значение равно NULL.

Если мьютекс является именованным мьютексом и объект существовал до этого вызова функции, возвращаемое значение является дескриптором существующего объекта, GetLastError возвращает ERROR_ALREADY_EXISTS, bInitialOwner игнорируется, и вызывающему потоку не предоставляется право собственности. Однако, если у вызывающей стороны есть ограниченные права доступа, функция завершится с ошибкой ERROR_ACCESS_DENIED, и вызывающая сторона должна использовать функцию OpenMutex.