
- •Порядок обработки сообщений, цикл обработки сообщений
- •Атрибуты контекста.
- •Порядок обработки сообщений, цикл обработки сообщений
- •Аппаратные сообщения
- •Символьные сообщения
- •Дочерние окна
- •Класс полос прокрутки
- •Класс редактирования
- •25 Класс окна списка
- •Способы хранения данных программы
- •Общие сведения о файле ресурсов
- •Меню и сообщения
- •Многозадачность и многопоточность
- •Вытесняющая многозадачность
- •Использование функции Sleep
- •36 Критические разделы
- •37 Использование событий
- •38 Многооконный интерфейс. Элементы mdi. Windows и mdi
- •39 Динамически подключаемые библиотеки. Типы связывания
Использование функции Sleep
поток – это часть программы, запускаемая параллельно другим задачам процесса. Поток сам определяет как долго ему находится в памяти и какие действия надо совершать. Если поток должен периодически совершать одни и те же действия (например, обновлять экран или проверять почту), то самым естественным способом сделать это является организация бесконечного цикла (подобного циклу обработки сообщений). Однако, в этом случае не определено время цикличности, т.к. временные периоды выполнения потока определены операционной системой. Кроме того, как только одна итерация цикла заканчивается, начинается другая. Как же вызвать приостановку выполнения потока? Для этих целей существует функция Sleep , которая в качестве единственного параметра имеет время, задаваемое в миллисекундах. Функция не осуществляет возврата до тех пор, пока не истечет указанное время. При этом другие потоки и процессы работают в обычных режимах. Если параметр этой функции равен нулю, то операционная система просто лишает текущий поток оставшегося кванта времени.
Следует отметить, что данная функция не освобождает полностью процессор от исполнения потока. Действительно, процессор периодически должен проверять истекло ли время, заданное в функции. То есть, речь идет не о приостановке периодического выполнения потока, а лишь о задержке выполнения алгоритма потока на одной его команде ( Sleep ).
36 Критические разделы
В многопоточной среде часто возникают проблемы, связанные с использованием параллельно исполняемыми потоками одних и тех же данных или устройств. Например, один из потоков, получает данные извне и помещает их в некоторый буфер памяти компьютера; Другой поток выбирает эти данные из буфера и отображает их на экран. Теперь представьте, что первый поток занес изменил только половину данных в буфере, операционная система переключилась на выполнение второго потока, и второй поток вывел на экран половину новых и половину старых данных.
В других случаях одновременное обращение к памяти может привести к неправильной работе программ, зависанию программы, потере данных и т.п.
Один из путей устранения конфликта состоит в том, что программист может определить участок потока, который должен быть выполнен без прерывания, т.е. пока участок потока не будет выполнен до конца, никакой из потоков данного процесса не будет выполняться.
Данный участок потока называется критическим разделом
37 Использование событий
Альтернативным вариантом синхронизации является использование событий. Объект событие может быть либо свободным ( signaled ) или установленным ( set ), либо занятым ( non-signaled ) или сброшенным ( reset). Вы можете создать объект "событие" с помощью функции:
hEvent = CreateEvent(&sa, fManual, fInitial, pszName);
Первый параметр - указатель на структуру SECURITY_ATTRIBUTES, устанавливающую параметры использования события потоками и процессами.
Параметр fInitial устанавливается в TRUE , если вы хотите, чтобы объект Событие был изначально свободным, или в FALSE, чтобы он был занятым.
Параметр pszName определяет имя события. По этому имени разные процессы могут использовать одно событие.
Для того, чтобы сделать свободным существующий объект Событие, надо вызвать функцию:
SetEvent(hEvent);
Чтобы сделать объект Событие занятым, вызывается функция:
ResetEvent(hEvent);
Для синхронизации используется функция:
WaitForSingleObject(hEvent, dwTimeOut);
где второй параметр имеет значение INFINITE. Возврат из функции происходит немедленно, если объект событие в настоящее время свободен. В противном случае поток будет приостановлен в функции до тех пор, пока событие не станет свободным. Вы можете установить значение тайм-аута во втором параметре, задав его величину в миллисекундах. Тогда возврат из функции произойдет, когда объект Событие станет свободным или истечет тайм-аут.
Если параметр fManual имеет значение FALSE при вызове функции CreateEvent , то объект Событие автоматически становится занятым, когда осуществляется возврат из функции WaitForSingleObject . Эта особенность позволяет избежать использования функции ResetEvent .