Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Организация потоковой обработки информации

Поиск

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

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

Первый способ предполагает размещение всей программы или ее частей в активной памяти, состоящей из ячеек команд. В каж­дую ячейку предусмотрена запись кода операции (идентификато­ра процедуры), всех необходимых операндов и адреса ячейки, в которую надлежит отправить результат. Готовые к выполнению команды, т. е. те, в тексте которых имеются все операнды, выби­раются исполнительными устройствами – вычислителями решающего поля для выполнения. Предполагается возможность одновре­менной выборки вычислителями достаточно большого числа гото­вых к выполнению команд. После выборки команды вычислителем операнды в ее тексте уничтожаются, что обеспечивает повторное выполнение команды в цикле. Результаты направляются по ука­занным в командах адресам в качестве операндов для последую­щего выполнения других команд. Данный способ требует разра­ботки специальной многовходовой активной памяти большого объ­ема, развитой переключающей сети, нуждается в решении ряда вопросов хранения и подкачки исходной информации, организа­ции процесса в случае, когда память команд не вмещает прог­рамму полностью, и т. д.

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

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

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

Для иллюстрации решения проблем, связанных с организацией потоковой обработки информации, выберем модель асинхронной модульной ВС, в которой применение указанных способов управления потоком данных сочетается с последовательной обработкой команд программы коммутации ВС состоит (рис. 4.1) из m про­цессоров коммутации (которые будем называть просто процессора­ми), памяти команд (ПК), адресного генератора (АГ) с табли­цами соответствия TC j, j=1,..., m, исполнительных устройств ре­шающего поля, буферов исполнительных устройств, оперативной памяти данных (ОПД). В состав исполнительных устройств вхо­дят вычислители Вi (с буферами Б i,), i=l,..., n, и процессор па­мяти (ПП), осуществляющий обмен информацией с ОПД и свя­занный со своим буфером – очередью заявок к памяти (ОЗП). Вы­числители могут быть построены на основе микро- и миниЭВМ, что способствует унификации устройств, реализации большого на­бора операций с учетом модификации и расширяемости, возмож­ности переменной комплектации, повышению надежности.

Рассмотрим кратко принципы работы такой ВС.

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

 

 

Р и с. 4.1. Схема ВС, управляемой потоком данных

 

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

При обработке основной группы команд из системы команд ВС процессор по дисциплине, реализуемой адресным генератором, занимает или использует ячейки команд буферов исполнительных устройств, организованных по первому способу управления потоком данных. Он записывает в эти ячейки коды операций и физи­ческие адреса ячеек команд буферов, в которые необходимо пере­дать результаты. Подобные же команды формируются в ОЗП. Команда на считывание располагает адресом ячейки команды в некотором буфере, куда должна направляться информация. При формировании команды записи ее адрес как адрес результата сообщается той команде, по которой он вырабатывается. Таким образом, процессор выполняет функции динамической коммутации исполнительных устройств для реализации второго уровня распараллеливания. Предусмотрены команды вычисления условных выражений, исключающие необходимость условных переходов при счете значений арифметических операторов. Это минимизирует задержки коммутации для определения направлений ветвления.

Асинхронно работающие исполнительные устройства (вычисли­тели и ПП) выполняют команды из своих буферов, располагаю­щие всеми операндами. Результаты направляются по указанным адресам, что реализует второй способ управления потоком дан­ных.

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

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

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

По мере того как частичная коммутация позволяет начать выполнение операций, исполнительные устройства выполняют пред­писанные им операции асинхронно после поступления на их вход необходимых операндов. Они передают результаты на входы дру­гих (или, в частности, этого же) исполнительных устройств в соответствии с необходимостью дальнейшей обработки информации, определенной данным алгоритмом и учтенной на этапе коммута­ции связей. При этом становится принципиально возможным аб­солютное распараллеливание участков выполняемого алгоритма, так как каждое исполнительное устройство получает возможность выполнения операции сразу же, как только будут получены от других исполнительных устройств необходимые операнды. От скорости процесса коммутации зависит возможность распараллеливания вычислений на уровне исполнительных устройств. Вместе с тем очевидно, что практически разница скоростей ком­мутации и выполнения не может быть столь значительной, что воз­можна и целесообразна коммутация связей исполнительных уст­ройств для выполнения всего алгоритма сразу. Да и ограничен­ный вычислительный ресурс этого не позволит. Поэтому по прог­рамме коммутации происходит постепенное «развертывание» гра­фа, отражающего вычислительный процесс.

 
4.2. Построение программ коммутации

Рассмотрим выражение

(4.1)

и соответствующую ему бесскобочную запись

(4.2)

Информационный граф G, соответствующий счету значения выражения (4.2), приведен на рис. 4.2. Его вершины, обозначенные символом операции, соответствуют элементарным операциям, к которым отнесем и счет значения квадратного корня.

В соответствии с индивидуальным заданием необходимо построить информационный граф. В качестве примера рассмотрим выражение (4.1), где a = 6, b = 8, c = 26, d = 7, e = 32, f = 90, g = 5, h =283, i = 1, j = 22, k = 298, l = 52, m = 64, тогда информационный граф G будет иметь вид (рис 4.3). Рядом с вершинами графа указаны промежуточные значения вычислений.

 

 

Р и с. 4.2. Информационный граф G

 

Предположим, что без учета ПП ВС обладает однородным решающим полем, т. е. все вычислители ВС способны выполнять все операции.

 

 

 

Рис. 4.3

 

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

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

Пусть каждый вычислитель В i обладает буфером Б i, i=l,..., n, состоящим из S адресуемых регистров для хранения назна­чаемых на вычислитель команд. Адреса регистров будем отожде­ствлять с номерами очереди использования данного вычислителя.

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

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

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

Одновременно с дальнейшим рассмотрением примера проде­монстрируем принцип трансляции записи исходного выражения (4.2) в программу коммутации вычислителей решающего поля.

Пусть решающее поле содержит четыре вычислителя (рис. 4.4), где Imn – регистры буферов, m – номер вычислителя, n – номер очереди).

Учитывая обусловленный выше порядок использования вычислителей, а также то, что в каждой цепочке операций первая про­изводится над одной или двумя величинами, имена которых указаны в предшествующей цепочке имен, наметим первый шаг их использования. Он соответствует выполнению первого яруса операций (второй ярус вершин в графе G).

Отразим это условной за­писью:

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

Даная схема отражает порядок выполнения вычислений и на ее основе строится логика работы программы. Вместо четырех вычислителей обработка данных производится четырьмя тредами (прил. П3).

На основе схемы коммутации счета (см. рис. 4.4) и листинга программы (см. прил. П3) рассмотрим порядок вычисления выражения.

Первый тред – функция Thread1():

1. Запуск треда.

2. Сложение (a+b).

3. Установка объекта события s 12 в состояние "включено". Этого события ожидает второй тред для продолжения вычислений. Таким образом, осуществляется синхронизация работы тредов.

4. Вычисление значения квадратного корня.

5. Вычитание (l - m).

6. Установка объекта события s 13 в состояние "включено", так как результат вычислений первого треда ожидает третий тред.

 

Р и с. 4.4. Схема коммутации счета

 

7. Ожидание результатов вычислений третьего и четвертого тредов.

8. Вывод результата.

Переход с одного этапа вычислений на другой сопровождается выводом сообщения в ListBox. Аналогично работе первого треда осуществляется работа и остальных тредов.

Составлению схемы коммутации счета способствует написание программы коммутации.

Пусть программа коммутации (табл. 4.1) состоит из трехадресных командных слов, в которых указывается код операции q, ад­реса А 1 и А 2 операндов, адрес результата А 3. Каждый адрес мо­жет быть адресом ОПД или вычислителя (на что указывает тег). Тогда на основе анализа возможности выполнения первой опера­ции из каждой цепочки операций можно записать первые пять команд программы.

При выполнении этих команд решающим полем организуется вызов величин а и b на первый регистр I 11 (см. рис. 4.4) вычислителя 1, величин с и d на регистр I 21 и т. д. Величина m поступает на второй регистр I 12 вы­числителя 1, так как все вычисли­тели один раз использованы. Рас­положение операндов в регистрах соответствует порядку, в котором указаны их имена или адреса выра­батывающих их вычислителей в команде.

Для продолжения процесса со­ставления программы коммутации предположим, что произошло вы­полнение первого яруса операций в графе G.

Таблица 4.1

Программа коммутации

Nk q A 1 A 2 A 3
  + a b (1, 1)
  + c d (2, 1)
  + e f (3, 1)
  ´ h i (4, 1)
  m   (1, 2)
  ´ (1, 1) (2, 1) (2, 2)
  + (3, 1) g (3, 2)
  ´ (4, 1) j (4, 2)
  i (1, 2) (1, 3)
  ´ (2, 2) (3, 2) (2, 3)
  ´ k (1, 3) (3, 3)
  (2, 3) (4, 2) (4, 3)
  : (4, 3) (3, 3) A

 

Учтем это, преобразовав выражение с использованием адресов вычислителей, на которых полу­чены результаты счета:

А (1,1) (2,1) ´ (3,1) g + ´ (4,1) j ´ - k l (1,2) - ´:: = (4.3)

Это бесскобочная запись выражения (4.1) при условии выполнения множества операций назначенными для этого вычислителями на первом шаге.

Применим на втором шаге для нее тот же прием планирования использования вычислителей, что и на первом шаге. Отразим его, преобразовав запись (4.3):

Эта запись иллюстрирует формирование команд 6 – 9 программы коммутации вычислителей на втором шаге.

С учетом дальнейшего условного выполнения операций вновь сформируем промежуточную бесскобочную запись счета значения исходного выражения, соответствующую выполнению второго яруса (третий ярус вершин) в графе G:

А (2,2) (3,2) ´ (4,2) – k (1,3) ´:: = (4.4)

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

Таким образом, на третьем шаге формируются команды 10 и 11, а запись преобразуется:

А (2,3) (4,2) – (3,3):: = (4.5)

На основе принятого порядка использования вычислителей на четвертом шаге формируется команда 12, предполагающая выпол­нение операции вычитания на вычислителе (4,3), и на пятом шаге формируется команда 13 получения окончательного резуль­тата А на вычислителе (1,4). На рис. 4.4 показана схема ком­мутации вычислителей для счета значения выражения (4.1).

Таким образом, программа коммутации вычислителей состав­ляется на основе анализа графа G по ярусам. Это способствует более раннему началу работы вычислителей при выполнении ра­бот в порядке предшествования операций.

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

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

ОРГАНИЗАЦИЯ ПАРАЛЛЕЛЬНЫХ

ВЫЧИСЛЕНИЙ СРЕДСТВАМИ

ОПЕРАЦИОННОЙ СИСТЕМЫ

Основными средствами выполнения параллельных вычислений в операционной системе является организация мультипрограммирования или мультипроцессорной обработки.

Мультипрограммирование – это способ организации вычислительного процесса, при котором на одном процессоре попеременно выполняются сразу несколько программ. Эти программы совместно используют не только процессор, но и другие ресурсы компьютера: оперативную и внешнюю память, устройства ввода-вывода, данные. [4]

Мультипроцессорная обработка – это способ организации вычислительного процесса в системах с несколькими процессорами, при котором несколько задач (процессов, потоков) могут одновременно выполняться на разных процессорах системы. [4]

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

В настоящее время большинство операционных систем (ОС) поддерживают режим мультипрограммирования. Однако только современные ОС реализуют мультипроцессорную обработку (Sun Solaris 2.x, Santa Crus Operations Open Server 3.x, IBM OS/2, Microsoft Windows NT и Novell Net Ware, начиная с 4.1).

Для организации мультипрограммирования в ОС различают следующие виды элементарных работ: процесс и поток.

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

Процесс обладает несколькими объектами: адресное пространство, выполняемый модуль (модули) и все, что эти модули создают или открывают. Как минимум, процесс должен состоять из выполняющегося модуля, личного адресного пространства и ветви. У каждого процесса, по крайней мере, одна ветвь. Фактически, ветвь – это выполняющаяся очередь. Например, когда ОС Windows впервые создает процесс, она создает только одну ветвь на процесс. Эта ветвь обычно начинает выполнение с первой инструкции в модуле. Если в дальнейшем понадобится больше ветвей, то ОС может сама создать их. Эти ветви называются потоками или тредами. Тред – это цепь инструкций.

Программист также может создавать дополнительные треды в программе. Таким образом, мультитрединг можно считать как многозадачность внутри одной программы. Если говорить в терминах непосредственной реализации, тред – это функция, которая выполняется параллельно с основной программой. Можно запустить несколько экземпляров одной и той же функции или несколько функций одновременно, в зависимости от требований. Мультитрединг свойственен Win32, под Win16 аналогов не существует.

Треды выполняются в одном процессе, поэтому они имеют доступ ко всем ресурсам процесса: глобальным переменным, хэндлам и т.д. Тем не менее, каждый тред имеет свой собственный стек, так что локальные переменные в каждом треде приватны. Каждый тред также имеет свой собственный набор регистров, поэтому, когда ОС Windows переключается на другой тред, предыдущий "запоминает" свое состояние и может "восстановить" его, когда он снова получает контроль. Это обеспечивается внутренними средствами ОС Windows.

Создание тредов при программировании осуществляется при помощи интерфейса прикладного программирования API (Application Programming Interface).

Наибольший эффект от введения многопоточной обработки достигается в мультипроцессорных системах, в которых потоки, в том числе и принадлежащие одному процессу, могут выполняться на разных процессорах действительно параллельно (а не псевдопараллельно). [4]

ПРИМЕР СОЗДАНИЯ МУЛЬТИПОТОЧНОГО

ПРИЛОЖЕНИЯ

Основой данного примера является арифметическое выражение 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



Поделиться:


Последнее изменение этой страницы: 2017-02-05; просмотров: 676; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.227.183.161 (0.012 с.)