Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учеб пособие по КР, СПО.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.72 Mб
Скачать

6. Пример создания мультипоточного

ПРИЛОЖЕНИЯ

Основой данного примера является арифметическое выражение 4.1, которое было рассмотрено в п. 4.2.

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

В качестве среды разработки использовался пакет Microsoft Visual C++ 6.0.

Первоначально создается проект File->New.

Рис. 6.1

На закладке Projects выбираем проект Win32Application. В поле Project Name указываем имя проекта, а в поле Location – его размещение. После нажатия кнопки OK переходим к следующему шагу создания проекта (рис. 6.2).

Рис. 6.2

В окне (рис. 6.2) выбираем An empty project, что соответствует созданию пустого проекта. После нажатия кнопки Finish создается пустой проект с заданным именем.

Далее переходим на поле Workspace, где отражена структура созданного проекта, первоначально состоящая из трех пустых папок: Source Files (файлы источники с расширением "cpp"), Header Files (заголовочные файлы с расширением "h"), Resource File (файлы ресурсов с расширением "rc"). Так как новый проект пустой, то нужно создать необходимые файлы. Для этого "щелчком" правой кнопки мыши по одной из трех папок вызываем контекстное меню и выбираем в нем пункт Add Files to Folder (Добавить файлы в папку) (рис. 6.3).

Рис. 6.3

Далее в следующем окне (рис. 6.4) необходимо указать имя создаваемого файла и его расширение.

Таким образом, создаем проект, который будет состоять из следующих файлов: Main.cpp (основной модуль), Main.h, Resource.rc (рис. 6.5).

После того как были созданы пустые файлы необходимо наполнить их содержанием.

Рис. 6.4

Рис. 6.5

Для этого откроем его двойным "щелчком" левой кнопки мыши. Далее на появившейся в центральном окне папке Resource "щелчком" правой кнопки мыши вызываем в контекстном меню пункт Insert (рис. 6.6).

Рис. 6.6

В появившемся окне выбираем Dialog и нажимаем кнопку New (рис. 6.7).

Рис. 6.7

Таким образом, создается новый диалог, на основе которого строится приложение (рис. 6.8).

После создания диалога среда программирования автоматически создает заголовочный файл Resource.h, который необходимо поместить в папку Header File.

Далее с использованием редактора ресурсов создаем интерфейс приложения, который будет иметь следующий вид (рис. 6.9).

Рис. 6.8

Рис. 6.9

В создаваемом приложении имеются: поля для ввода переменных (a, b, c, … m), поле View thread steps, предназначенное для вывода информации о состоянии тредов, а также кнопки Start и Terminate, соответственно для запуска и прерывания процесса вычисления.

Далее с помощью интегрированного текстового редактора пишем исходный код программы, реализующей вычисление арифметического выражения при помощи четырех тредов, согласно созданному интерфейсу приложения. Исходный текст программы поместим в файлы Main.cpp и Main.h (рис. 6.10).

Рис. 6.10

Рассмотрим принцип функционирования приложения. Листинги текста программы приведены в прил. П3, П4, а описание используемых функций и их параметров – в прил. П2.

Первоначально директивой препроцессора #include подключаем необходимые заголовочные файлы. Далее объявляем глобальные переменные и массивы переменных, так как в качестве общих данных несколько тредов могут использовать только глобальные переменные. После этого необходимо организовать точку входа. В Windows-приложениях для этого существует функция WinMain(). В теле этой функции организуем цикл по созданию объектов события – эти объекты необходимы для синхронизации тредов. Далее используем функцию, создающую диалоговое окно DialogBoxParam(). В качестве одного из параметров этой функции используется указатель на функцию обработки диалогового окна DlgProc(). В этой функции осуществляется обработка сообщений.

Так при нажатии на кнопку Start проверяем введенные значения, если какая-либо переменная отсутствует, то выводим сообщение с помощью функции MessageBox(). Получение значений входных переменных осуществляется функцией GetOurVariables(). Если переменные введены, то очищаем ListBox при помощи функции SendDlgItemMessage(). Далее организуем цикл по созданию тредов, создание которых осуществляется функцией CreateThread(). В этом же цикле осуществляется установка уровня приоритета тредов – функция SetThreadPriority(), а также, выполнение тредов - функции Thread1, Thread2, Thread3, Thread4.

Рассмотрим более детально функции тредов на примере функции Thread1. В этой функции используется макроподстановка, позволяющая осуществить вывод состояний тредов в ListBox – функция addstr(). Согласно схеме коммутации каждый тред выполняет определенные действия (вычисления), а также с помощью функций SetEvent(), WaitForMultipleObjects() и WaitForSingleObject() осуществляется синхронизация тредов.

При нажатии кнопки Terminate запускается цикл, в котором осуществляется грубое прерывание тредов функцией TerminateThread(). Далее при помощи функции EnableWindow() кнопка Start становится активной, а кнопка Terminate деактивированной. Одним из параметров этой функции является функция GetDlgItem() – функция, возвращающая хендл элемента управления диалогового окна.

При создании диалога обрабатывается сообщение WM_INITDIALOG, при этом используется функция SendMessage().

Обработка сообщения WM_CLOSE осуществляется функцией, корректно закрывающей диалоговое окно EndDlg().

После того, как текст программы написан, необходимо скомпилировать проект, а затем получить исполняемый модуль. Для этого выбираем из меню Build пункт Rebuild All (рис. 6.11).

Рис. 6.11

Если не возникает ошибок, то в итоге получаем исполняемый модуль, реализующий вычисление арифметического выражения (4.1) с использованием четырех тредов. При возникновении каких-либо ошибок их необходимо устранить. Для устранения ошибок можно использовать встроенный отладчик.

При инициализации полученного исполняемого файла запускается приложение (рис. 6.12).

Рис. 6.12

Далее необходимо ввести значения переменных, например, используемых в п. 4.2, тогда в результате вычислений получаем рис. 6.13.

Рис. 6.13

В поле View threads steps отражается состояние тредов и этапы вычислений (рис. 6.14)

Рис. 6.14