- •Лабораторный практикум «Основы разработки приложений Windows» Книга 2
- •Часть 1. Теоретические сведения4
- •Часть 2. Лабораторный практикум73
- •Часть 1 Теоретические сведения
- •1. Основы архитектурЫ защищенного режима Регистры процессора
- •Адресация памяти
- •2. Логические шрифты Создание логических шрифтов
- •Вывод на экран текстовых строк
- •3. Таймеры Windows Организация и обслуживание таймеров
- •Мультимедийные таймеры
- •Измерение интервалов времени
- •Организация периодического процесса
- •Задание однократного интервала времени
- •4. Дочерние окна Создание и использование дочерних окон
- •Окна предопределенных классов в главном окне
- •5. Вывод растровых изображений
- •Процедура вывода растрового изображения
- •Компоновка составных изображений
- •6. Обслуживание файлов в 32-разрядных приложениях Windows
- •Базовые операции с файлами Открытие и создание файла
- •Запись и чтение файла
- •Файлы, проецируемые в память
- •7. Процессы и потоки
- •Создание дочернего процесса
- •Создание дочернего потока
- •Синхронизация потоков Общие характеристики объектов Windows
- •Синхронизация с помощью состояний потока
- •Синхронизация с помощью событий
- •Критические секции и защита данных
- •8. Библиотеки динамической компоновки
- •Часть 2 Лабораторный практикум Работы лабораторного практикума Работа 1. Создание логических шрифтов
- •Работа 2. Таймеры Windows(индивидуальное задание а)
- •Работа 3. Дочернее окно в главном окне приложения
- •Работа 4. Вывод растровых изображений с использованием совместимой памяти
- •Работа 5. Измерение временных характеристик программы с помощью мультимедийного таймера
- •Работа 6. Вывод движущихся изображений с синхронизацией от системного таймера (индивидуальное задание b)
- •Работа 7. Повышение качества движущихся изображений с помощью совместимой памяти
- •Работа 8. Движение изображения по фоновому рисунку
- •Работа 9. Работа с файлами (индивидуальное задание c)
- •Работа 10. Стандартные диалоги Windows для работы с файлами
- •Работа 11. Проецирование файла в память
- •Работа 12. Потоки (индивидуальное задание d)
- •Работа 13. Синхронизация потоков с помощью событий
- •Работа 14. Защита данных с помощью критической секции
- •Работа 15. Библиотеки динамической компоновки
- •Работа 16. Передача параметров в функции dll-библиотек
- •Индивидуальные задания лабораторного практикума
- •Задание c2.Массив записываемых в файл данных должен представлять собой последовательный ряд из 2000 целых четных чисел.
- •Лабораторный практикум «Основы разработки приложений Windows» Книга 2
Синхронизация потоков Общие характеристики объектов Windows
Организация программного комплекса, состоящего из нескольких процессов или потоков, почти неминуемо приводит к необходимости синхронизации выполняемых фрагментов программы. Синхронизация может иметь различные аспекты: сообщение потоку о завершении другого потока или его фрагмента, запрет потоку обращаться к некоторым данным, пока с ними работает другой поток, наложение ограничений на количество потоков, использующих одни и те же данные, и др.
Синхронизация процессов и входящих в них потоков осуществляется с помощью различных объектов Windows, к которым относятся как сами процессы и потоки, так и программные средства, созданные специально для целей синхронизации: критические секции, мьютексы, семафоры, события и некоторые другие. Мы рассмотрим только синхронизацию потоков с помощью самих же потоков, а также событий.
Для объектов, которые могут служить целям синхронизации, в системе Windows предусматриваются два состояния – свободное, или сигнальное (signaled), и занятое, или несигнальное (nonsignaled). Занятое состояние объекта используется для запрета тех или иных программных действий; свободное состояние, наоборот, снимает запрет и разрешает эти действия.
Имеются различные способы как изменения состояния синхронизирующего объекта, так и анализа его состояния. Для некоторых объектов имеются функции, позволяющие переводить объект в требуемое (свободное или занятое) состояние. Например, для объекта “событие” (event) функцияSetEvent()устанавливает объект в свободное (сигнальное) состояние, а функцияResetEvent(), наоборот, сбрасывает его в занятое состояние. В соответствии с именами этих функций свободное состояние объекта называют еще установленным (set), а занятое – сброшенным (reset).
Анализ состояния объекта осуществляется с помощью двух основных функций синхронизации – WaitForSingleObject()иWaitForMultipleObjects(). Суть их одинаковая – они останавливают выполнение потока, “усыпляя” его, если анализируемый объект занят, и разрешают потоку дальнейшее выполнение (“будят” поток), как только объект освобождается. При этом первая из двух упомянутых выше функций позволяет анализировать состояние только одного объекта Windows, а вторая функция может анализировать состояние группы объектов.
Усыпление потока является высокоэффективной системной операцией, которая почти не требует процессорного времени. Поэтому в то время как один или несколько потоков спят в ожидании некоторого события, остальные действующие в системе потоки забирают себе практически все процессорное время. Как только ожидаемое событие произойдет, спящий поток мгновенно пробуждается и продолжает свое выполнение.
Функция WaitForSingleObject()имеет следующий прототип:
DWORD WaitForSingleObject(
HANDLE hObject,//Дескриптор синхронизирующего объекта
DWORD dwTimeout//Лимит времени ожидания в миллисекундах
);
Если нам нужно, чтобы функция ожидала событие неограниченное время, в качестве второго параметра следует задать константу INFINITE.
Мы видим, что функция ожидания освобождения объекта требует указания дескриптора этого объекта. Вообще для объектов Windows характерно обладание тремя описателями: дескриптором, именем и состоянием. Как мы уже видели, дескриптор объекта возвращается функциями, которые этот объект либо создают, либо открывают; обычно дескриптор используется для обращения к объекту внутри процесса (хотя, возможно, и из другого потока). Имя объекта, если оно необходимо, также задается объекту на этапе его создания; оно является общесистемной характеристикой и служит для обращения к объекту из другого процесса. Что касается состояния, то для объектов, которые будут рассматриваться в этом разделе, характерны следующие состояния:
Поток – состояние сбрасывается при создании потока и устанавливается при его завершении.
Событие – требуемое состояние события задается при его создании функцией CreateEvent(). Кроме того, событие может быть установлено в процессе выполнения потока явным образом функциейSetEvent()или сброшено функциейResetEvent(). В некоторых случаях, когда события используются в асинхронных операциях, состояние события задается системой.