Синхронизация потоков в операционной системе Windows, страница 8

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

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

Чаще всего мьютексы используются для синхронизации процессов, однако в некоторых случаях мьютексы используют для обеспечения синхронной работы нескольких потоков в рамках одного процесса. Конечно, для синхронизации потоков допускается использовать мьютексы, однако более высокой производительности можно достичь при использовании критических секций (critical section), Критическая секция — это форма мьютекса, предназначенная для использования в рамках одного процесса. Помимо этого критическая секция обладает рядом других ограничений, о которых будет рассказано несколько позже в данной главе,

Листинг 2 содержит исходный код простой программы, демонстрирующей применение основных функций работы с мьютексами. Запустите программу. Программа получает в собственное владение мьютекс и отображает на экране простое окно сообщения (message box). He убирайте это окно с экрана. Вместо этого запустите вторую копию программы. Вторая копия не сможет завладеть мьютексом до тех пор, пока первая копия не завершит работу. Другими словами, каждая новая копия программы будет ждать, пока вы не щелкнете по кнопке диалогового окна, тем самым убрав это окно с экрана и завершив работу программы. Если вы запустили несколько копий программы, в любой момент времени только одна из них сможет вывести на экран окно сообщения.

Листинг 2. Тестирование работы с мьютексом

#include <windows.h>

#include <iostream.h>

void main()

{

          HANDLE mtx=CreateMutex(NULL, FALSE, "NT5BBMTX");

          cout<<"Проверить мьютекс\n";

          cout.flush();

          WaitForSingleObject(mtx, INFINITE);

          cout<<"Мьютекс получен!\n";

          cout.flush();

          MessageBox(NULL,"Программа захватила мьютекс", "MUTEX", MB_OK);

          ReleaseMutex(mtx);

          CloseHandle(mtx);

}

Подробнее о семафорах

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

Таблица 4

Вызов

Назначение

CreateSemaphore OpenSemaphore ReleaseSemaphore

Создает новый семафор или открывает существующий

Открывает существующий семафор

Добавляет некоторое значение (обычно 1) к счетчику семафора, делая его доступным для большего количества потоков

Если поток обращается к семафору дважды, значение счетчика семафора уменьшается на две единицы. В этом семафоры отличаются от мьютексов, так как если поток несколько раз обращается к мьютексу, это расценивается как одно oбpaщение.