Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора 130стр.doc
Скачиваний:
93
Добавлен:
15.06.2014
Размер:
2.49 Mб
Скачать

27) Реализация многопоточных приложений с использованием библиотеки mfc.

Два типа многозадачности: на процессах; на потоках.

Для потоковой многозадачности в MFC предусмотрены специальные средства поддержки:

Синхронизация позволяет контролировать выполнение потоков (и процессов) строго определенным образом. Библиотека классов MFC полностью поддерживает средства многозадачности.

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

В MFC определены два типа потоков: интерфейсные и рабочие.

Интерфейсный принимает и обрабатывает сообщения.(главный поток -интерфейсный)

Рабочие не принимают и не обрабатывают сообщения - обеспечивают дополнительные пути выполнения задачи внутри интерфейсного потока.

В MFC потоковая многозадачность реализуется с помощью класса CWinThread, работая в многозадачном режиме, надо включать стандартный библиотечный файл afxmt.h.

Чаще используются рабочие потоки.

Создание рабочего потока

Ф-ция создания: AfxBeginThread библиотеки MFC:

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

При успешном завершении функция AfxBeginThread возвращает указатель на объект потока, в противном случае возвращает ноль.

Поток может также “завершить сам себя” - AfxEndThread библиотеки MFC. Параметр этого метода содержит статус завершения потока.

Как правило, лучше давать потоку возможность нормально завершиться одновременно с потоковой функцией.Иногда бывает необходимо приостановить поток на заданное количество миллисекунд: ф-ция Sleep.

Использование нескольких потоков

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

Остановка и возобновление выполнения потоков

Остановить выполнение потока - SuspendThread класса CWinThread, после этого поток не выполняется. Продолжение выполнения - ResumeThread класса CWinThread.

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

С вызовом SuspendThread значение счетчика остановок увеличивается на 1,а при ResumeThread - уменьшается на 1. Остановленный поток может продолжить выполнение только после того, как значение счетчика достигнет нуля.

Управление приоритетами потоков

установка приоритета - комбинация двух значений: значения общего класса приоритета процесса и значения приоритета самого потока относительно данного класса. Фактический приоритет потока определяется путем сложения класса приоритета процесса и уровня приоритета самого потока.

Приоритет потока показывает, сколько времени работы процессора требуется потоку. Для потоков с низким приоритетом требуется мало времени, а для потоков с приоритетом - много времени.

Получение класса приоритета - GetPriorityClass, а установление - SetPriorityClass.

REALTIME_PRIORITY_CLASS

HIGH_PRIORITY_CLASS

NORMAL_PRIORITY_CLASS

IDLE_PRIORITY_CLASS

Приоритеты потоков контролируются методами класса CWinThread. Определить значение приоритета можно с помощью метода GetThreadPriority, а изменить - SetThreadPriority

THREAD_PRIORITY_TIME_CRITICAL

THREAD_PRIORITY_HIGHEST

THREAD_PRIORITY_ABOVE_NORMAL

THREAD_PRIORITY_NORMAL

THREAD_PRIORITY_BELOW_NORMAL

THREAD_PRIORITY_LOWEST

THREAD_PRIORITY_IDLE

Синхронизация потоков

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

Механизм, обеспечивающий процесс синхронизации, называется ограничением доступа.

Необходимость в нем возникает также в тех случаях, когда один поток ожидает события, генерируемого другим потоком. Имеется два общих состояния, в которых может находиться задача.

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

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

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

28) Ресурсы Windows. Способы задания ресурсов Windows-приложения и их использования.

Ресурсы бывают системные и определяемые пользователем.

К стандартным ресурсам относятся:

  • Таблица акселераторов, т.е перечисляются комбинаиции клавиш и команды, которые должны быть посланы

  • Значок (иконка) или битовый образ. Битовые образы хранятся в файлах с расширением .BMP. В файле описания ресурсов ссылка на файл значка выглядит примерно так:

myicon ICON iconfile.ico, где ICONFILE.ICO — имя файла значка. В этой инструкции значку присваивается имя «myicon». В программе на С для получения описателя значка используется функция LoadIcon. В функции LoadIcon имеется два параметра. Первым является описатель экземпляра программы, который в WinMain обычно называется hInstance. Этот описатель требуется для Windows, чтобы определить, в каком файле с расширением .EXE содержится ресурс значка. Вторым параметром является имя значка из описания ресурсов, заданное в виде указателя на оканчивающуюся нулем строку. Возвращаемым значением функции LoadIcon является значение типа HICON, которое определяется в WINDOWS.H.

Вместо имени вы также можете использовать число. Это число называется идентификатором (ID) значка.

125 ICON iconfile.ico

hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (125));

MAKEINTRESOURCE является макросом, определенным в заголовочных файлах Windows, который преобразует число в указатель. Так Windows узнает, что второй параметр функции LoadIcon является числом, а не указателем на символьную строку. IDI_APPLICATION также определяется в заголовочных файлах Windows с использованием макроса MAKEINTRESOURCE: #define IDI_APPLICATION MAKEINTRESOURCE (32512)

Хотя для обозначения программ Windows использует значки несколькими способами, во множестве программ для Windows значок задается только при определении класса окна:

wndclass.hIcon = LoadIcon(hInstance, “MyIcon”);

wndclass.hIconSm = LoadIcon(hInstance, “MySmIcon”);

  • Диалоговое окно

  • Расширенный метафайл

  • Шрифт

  • Курсор. Инструкции для задания курсора в файле описания ресурсов и для получения описателя курсора в программе очень похожи на инструкции для значков:

mycursor CURSOR cursfile.cur

hCursor = LoadCursor (hInstance, «mycursor»);

Использование идентификаторов и MAKEINTRESOURCE также работают и для курсоров. В заголовочные файлы Windows включается определение typedef HCURSOR, которое можно использовать для хранения описателя курсора. Вы можете использовать описатель курсора, полученный при вызове функции LoadCursor, при задании поля hCursor структуры класса окна:

wndclass.hCursor = LoadCursor (hInstance, “mycursor”);

  • Растровое изображенеие (bitmap) Битовые образы используются в двух главных целях. Первая — рисование на экране картинок. Вторая цель использования битовых образов — создание кистей.

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

  • Строковые таблицы. Набор строк (у каждой свой ID, свой язык написания), которые хранятся в формате Unicode, каждому символу отводится 2 байта. Файл представлен как набор сообщений, для каждого указано, чем оно послано и его перевод.

  • Информация о версии.

  • Таблица сообщений.

Ресурсы являются данными и они хранятся в .EXE файле программы. К ресурсам нет непосредственного доступа через переменные, определенные в исходном тексте программы. Они должны быть явно загружены из файла с расширением .EXE в память. Когда Windows загружает в память код и данные программы для ее выполнения, она обычно оставляет ресурсы на диске. Только тогда, когда Windows нужен конкретный ресурс, она загружает его в память. При создании программы ресурсы определяются в файле описания ресурсов, который представляет собой файл с расширением .RC. С помощью компилятора ресурсов файл описания ресурсов компилируется и становится бинарным файлом с расширением .RES, который присоединяется либо к подключаемому модулю, либо к библиотеке. В описание ресурсов можно добавить заголовочный файл.

Ресурсы, определяемые пользователем удобны для включения самых разнообразных данных в ваш файл с расширением .EXE и получения доступа в программе к этим данным. Можно добавлять свои ресурсы при помощи: #ifdef, #define, #include.

helptext TEXT proghelp.txt

hResource = LoadResource (hInstance,

FindResource (hInstance, "TEXT", "helptext")) ;

Когда нужно получить доступ к тексту:

pHelpText = LockResource (hResource);

Освободить оперативную память:

FreeResource (hResource);