Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный практикум «Основы разработки приложений Windows» книга 2.DOC
Скачиваний:
91
Добавлен:
10.05.2014
Размер:
827.9 Кб
Скачать

Синхронизация потоков Общие характеристики объектов Windows

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

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

Для объектов, которые могут служить целям синхронизации, в системе Windows предусматриваются два состояния – свободное, или сигнальное (signaled), и занятое, или несигнальное (nonsig­naled). Занятое состояние объекта используется для запрета тех или иных программных действий; свободное состояние, наоборот, снимает запрет и разрешает эти действия.

Имеются различные способы как изменения состояния синхронизирующего объекта, так и анализа его состояния. Для некоторых объектов имеются функции, позволяющие переводить объект в требуемое (свободное или занятое) состояние. Например, для объекта “событие” (event) функцияSetEvent()устанавливает объект в свободное (сигнальное) состояние, а функцияResetEv­ent(), наоборот, сбрасывает его в занятое состояние. В соответствии с именами этих функций свободное состояние объекта называют еще установленным (set), а занятое – сброшенным (reset).

Анализ состояния объекта осуществляется с помощью двух основных функций синхронизации – WaitForSingleObject()иWaitForMultipleObjects(). Суть их одинаковая – они останавливают выполнение потока, “усыпляя” его, если анализируемый объект занят, и разрешают потоку дальнейшее выполнение (“будят” поток), как только объект освобождается. При этом первая из двух упомянутых выше функций позволяет анализировать состояние только одного объекта Windows, а вторая функция может анализировать состояние группы объектов.

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

Функция WaitForSingleObject()имеет следующий прототип:

DWORD WaitForSingleObject(

HANDLE hObject,//Дескриптор синхронизирующего объекта

DWORD dwTimeout//Лимит времени ожидания в миллисекундах

);

Если нам нужно, чтобы функция ожидала событие неограниченное время, в качестве второго параметра следует задать константу INFINITE.

Мы видим, что функция ожидания освобождения объекта требует указания дескриптора этого объекта. Вообще для объектов Windows характерно обладание тремя описателями: дескриптором, именем и состоянием. Как мы уже видели, дескриптор объекта возвращается функциями, которые этот объект либо создают, либо открывают; обычно дескриптор используется для обращения к объекту внутри процесса (хотя, возможно, и из другого потока). Имя объекта, если оно необходимо, также задается объекту на этапе его создания; оно является общесистемной характеристикой и служит для обращения к объекту из другого процесса. Что касается состояния, то для объектов, которые будут рассматриваться в этом разделе, характерны следующие состояния:

  • Поток – состояние сбрасывается при создании потока и устанавливается при его завершении.

  • Событие – требуемое состояние события задается при его создании функцией CreateEvent(). Кроме того, событие может быть установлено в процессе выполнения потока явным образом функциейSetEvent()или сброшено функциейResetEvent(). В некоторых случаях, когда события используются в асинхронных операциях, состояние события задается системой.