Синхронизация потоков с использованием объектов ядра: Методические рекомендации по выполнению лабораторной работы

Страницы работы

Содержание работы

Синхронизация потоков с использованием объектов ядра

                                          Лабораторная     работа     № 3

                                                1.   ЦЕЛЬ   РАБОТЫ

Изучение принципов использования объектов синхронизации режима ядра для обеспечения монопольного доступа потоков к разделяемым ресурсам, приобретение практических навыков использования средств API Windows для создания многопоточных[ приложений.

                   2. СИНХРОНИЗИРУЮЩИЕ ОБЪЕКТЫ РЕЖИМА ЯДРА

Критические секции (см. л.р. №2) не являются объектами ядра, поэтому их можно использовать для синхронизации доступа к разделяемым ресурсам лишь в рамках одного процесса.

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

     Следующие объекты ядра используются для синхронизации доступа любых потоков к разделяемым ресурсам:

·  мьютексы

·  события

·  семафоры

  • таймеры  ожидания

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

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

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

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

DWORD WaitForSingleObject(HANDLE hObject, DWORD dwTimeOut);

где  hObject –дескриптор  объекта, dwMilliseconds указывает, сколько времени (в миллисекундах) поток готов ждать освобождения объекта.

    В качестве значения параметра dwTimeOut используют три варианта:

   dwTimeOut

                                              Действия

          0

    Функция только проверяет состояние объекта (занят или свободен) и сразу же   

    возвращается

    Число

    МСек

    Функция ожидает освобождения объекта не более указанного времени

    INFINITE

     Время ожидания бесконечно. Если объект так и не освободится, поток никогда не получит процессорного времени

       Функция WaitForSingleObject может возвращать одно из следующих значений:

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

                            Описание

WAIT_TIMEOUT

    Объект не перешел в свободное состояние, но интервал времени        

     истек

WAIT_ABANDONED

     Ожидаемый объект является мьютексом, который не был освобожден владеющим им потоком перед окончанием этого потока. Объект мьютекс автоматически переведен системой в свободное состояние.

WAIT_OBJECT_0

     Объект перешел в свободное состояние

WAIT_FAILED

Произошла ошибка, причину которой можно узнать, вызвав GetLastError

Вот пример ожидания освобождения некоторого обобщенного объекта с дескриптором hObject:

DWORD dw = WaitForSlngleObject(hObject, 5000);

switch (dw)
   {
      case WAIT_OBJECT_0: //
объектсвободен
                          break;

      case WAIT_TIMEOUT: // объект не освободился в течение 5000 мс
                          break;

      case WAIT_FAILED: // некорректный вызов функции
                         break;
   }

                                                        Мьютексы

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

     Для использования объекта-мьютекса один из процессов должен сначала создать его вызовом функции:

HANDLE CreateMutex(

                      PSECURITY_ATTRIBUTES psa,

                      BOOL fInitialOwner,

                      PCTSTR pszName

                  );

      Параметр psaобычно равен NULL.

      Параметр fInitialOwnerопределяет начальное состояние мъютекса. Если в нем передается false (что обычно и бывает), мьютекс изначально не захвачен никаким  потоком  и  находится в свободном состоянии. Если же в нем передается true, мьютекс считается захваченным потоком, создавшим его.

      Параметр pszNameимя мьютекса (char-строка), возможно пустое.

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

      Любой другой процесс может получить свой «процессо-зависимый» дескриптор существующего объекта «мьютекс», вызвав OpenMutex:

  HANDLE OpenMutex( DWORD fdwAccess, BOOL bInheritHandle, PCTSTR pszName);

Чтобы это выполнить, нужно знать имя мьютекса, которое просвоено ему при создании.

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

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

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

                BOOL ReleaseMutex(HANDLE hMutex);

Похожие материалы

Информация о работе