Ожидание завершения потока

Поток может дожидаться завершения выполнения другого потока точно так же, как потоки могут дожидаться завершения процесса, что обсуждалось в главе 6. В этом случае при вызове функций ожидания (WaitForSingleObject и WaitForMultipleObjects) вместо дескрипторов процессов следует использовать дескрипторы потоков. Заметьте, что не все дескрипторы в массиве, передаваемом функции WaitForMultipleObjects, должны быть обязательно одного и того же типа; например, в одном вызове могут быть одновременно указаны дескрипторы потоков, процессов и других объектов.

Допустимое количество объектов, одновременно ожидаемых функцией WaitForMultipleObjects, ограничено значением MAXIMUM_WAIT_OBJECTS (64), но при большом количестве потоков можно воспользоваться серией вызовов функций ожидания. Эта техника уже была продемонстрирована в программе 6.1; программы, приведенные в книге, ожидают завершения выполнения одиночных объектов, но на Web-сайте приведены полные решения.

Функция ожидания дожидается, пока объект, указанный дескриптором, не перейдет всигнальное состояние. В случае потоков объект потока переводится в сигнальное состояние при помощи функций ExitThread и TerminateThread, что приводит к освобождению всех других потоков, дожидающихся перехода данного объекта в сигнальное состояние, включая и те потоки, которые могли оставаться в состоянии ожидания и впоследствии, после того, как поток завершится. Дескриптор потока, перешедший в сигнальное состояние, не выходит из этого состояния. То же самое остается справедливым и по отношению к дескрипторам процессов, но не относится к дескрипторам некоторых других объектов, например, мьютексов и событий (описываются в следующей главе).

Заметьте, что дожидаться перехода в сигнальное состояние одного и того же объекта могут одновременно несколько потоков. Аналогично, функция ExitProcess переводит в сигнальное состояние как сам процесс, так и все его потоки.

ЭКЗАМЕНАЦИОННЫЙ БИЛЕТ № 18

1. Ресурсы. Акселераторы.

Понятие ресурсов

Структура EXE-файла для Windows такова, что в его конец могут быть записаны некоторые данные, совершенно не зависимые от самой программы. Они называются ресурсами. Они могут редактироваться совершенно раздельно, хотя находятся в том же файле, где код и данные. При загрузке программы на выполнение ресурсы обычно не загружаются в память, а это делается лишь по запросу от программы. В ресурсах программист может хранить любые данные какого угодно размера. Но есть стандартные типы ресурсов, такие как иконки, битовые образы, курсоры, диалоги, меню. Большинство диалоговых окон, которые Вы видели в программах, не создаются программным путем, а просто их шаблоны загружаются из ресурсов. Сами шаблоны, как и другие ресурсы, редактируются визуально с помощью специальных ресурсных редакторов.

При сборке проекта приложения, ресурсы добавляются к EXE-файлу уже после линковки. Для описания ресурсов существует специальный язык, а сами описания хранятся в текстовых файлах с расширением rc. Раньше программисты вручную писали сценарии ресурсов на языке ресурсов, сейчас же так никто не делает, а используются визуальные редакторы. Перед добавлением к исполняемому файлу сценарии преобразуются в бинарный вид с помощью компилятора ресурсов, в результате чего получается файл с расширением res. Как правило, все эти шаги выполняются автоматически при работе из интегрированной среды Visual C++. Вообще, ручное редактирование ресурсных сценариев требуется сейчас уже очень редко, лишь при определении нестандартных ресурсов в сложных проектах. Мы будем использовать только интегрированную среду, как это сейчас делают многие программисты.

Каждый ресурс имеет свой уникальный идентификатор. Это может быть либо строка, либо число (константа). Числа можно использовать всегда, а строки - не всегда. Мы будем использовать и то, и другое. Редактор ресурсов из Visual C++ помещает имена констант в файл resource.h, который нужно включить в файлы программы. Стандартные идентификаторы хранятся в файле afxres.h, который обычно используется автоматически ресурсным редактором.

Меню

Меню обычно создаются визуально. В Visual C++ нужно нажать клавиши Ctrl+2 или нажать кнопку создания нового меню на панели инструментов. Среда автоматически добавит в проект сценарий ресурсов и перейдет к редактированию меню.

При создании меню, для отдельных пунктов могут быть установлены опции выделения серым цветом (в этом случае при выполнении программы пункт меню будет недоступен), вставки разделительной горизонтальной черты, перехода на новую строку (в этом случае пункты верхнего уровня будут начинаться с новой строки, а нижнего - в новом столбце через вертикальную черту). Скорее всего, Вы уже видели все эти элементы в реальных программах.

Меню, как отдельному ресурсу, должен быть присвоен числовой или символьный идентификатор. При редактировании символьные идентификаторы заключаются в кавычки. Также, каждому пункту меню должен быть присвоен уникальный числовой идентификатор. Это позволит программе реагировать на выбор пункта в меню, в этом случае MFC будет вызывать соответствующий обработчик (об этом несколько позже). По принятому соглашению, все идентификаторы пунктов меню начинаются с IDM_. В самих названиях пунктов можно указывать ключевые клавиши, поставив перед буквой символ &. В этом случае, если меню активно, пункт можно выбрать также и с клавиатуры.

На рис. 5 показан процесс создания меню в среде Visual C++. Другие ресурсы создаются аналогично. Этот процесс довольно прост.

Ожидание завершения потока - student2.ru
Рис. 5. Процесс визуального создания меню в среде Visual C++

Наши рекомендации