Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
28
Добавлен:
17.04.2013
Размер:
129.54 Кб
Скачать

Использование объекта mutex

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

BOOL WriteToDatabase(HANDLE hMutex)

{

DWORD dwWaitResult;

dwWaitResult = WaitForSingleObject( hMutex, 5000L);

switch (dwWaitResult)

{

case WAIT_OBJECT_0: // нить владеет объектом mutex.

//***********************

// Запись в базу данных.

//***********************

// Освобождаем mutex.

if (! ReleaseMutex(hMutex)) {

// Обработка ошибки.

}

break;

}

case WAIT_TIMEOUT: // Истекло время ожидания (5 сек).

return FALSE;

}

return TRUE;

}

Семафор

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

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

Каждый раз при возврате из wait функции счетчик семафора уменьшен на один. Функция ReleaseSemaphore увеличивает счетчик семафора на указанное количество. Счетчик никогда не может быть меньше нуля или больше максимального значения.

В отличие от объекта mutex, функцию ReleaseSemaphore может использовать любая нить, чтобы увеличить счетчик семафора.

Использование семафора

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

HANDLE hSemaphore;

LONG cMax = 10;

LONG cPreviousCount;

// Create a semaphore with initial and max. counts of 10.

hSemaphore = CreateSemaphore(

NULL, // no security attributes

cMax, // initial count

cMax, // maximum count

NULL); // unnamed semaphore

if (hSemaphore == NULL) { // Check for error. }

// Try to enter the semaphore gate.

dwWaitResult = WaitForSingleObject( hSemaphore, 0L);

switch (dwWaitResult) {

case WAIT_OBJECT_0: // The semaphore object was signaled.

// OK to open another window.

break;

case WAIT_TIMEOUT: // А time-out occurred.

// Cannot open another window.

break;

}

// When thread closes a window, increment the count of the semaphore.

if (!ReleaseSemaphore(

hSemaphore, // handle to semaphore

1, // increase count by one

NULL) ) // not interested in previous count

{

// Deal with the error.

}

Событие

Объект события - объект синхронизации, состояние которого может быть явно установлено сигнализированным при помощи функции SetEvent или PulseEvent. Существуют два типа событий.

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

События с автоматическим сбросом.События, состояние которых остается «сигнализирован» до момента выполнения функции wait, в это время система автоматически сбрасывает состояние «сигнализирован». Если никакие нити не ожидают данное событие, то его состояние остается «сигнализирован».

Нить использует функцию CreateEvent, чтобы создать объект при этом определяется начальное состояние объекта и тип события (с ручным или автоматическим сбросом). Можно также определить имя объекта, тогда нити в других процессах могут открывать дескриптор к существующему объекту в вызове функции OpenEvent.

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

Соседние файлы в папке вар1