Блок схема 3 - Вычисление
отклонений каждого значения от среднего арифметического
3. Описание методов создания,
уничтожения и синхронизации потоков, примененных в программе
.1 Создание потоков
Для создания многопоточных приложений в
C++Builder реализован абстрактный класс TThread.- абстрактный класс, который
допускает создание отдельных потоков выполняющихся в приложении.
Создайте потомка класса TThread, чтобы
представить выполняемый поток в многопоточном приложении.
Каждый новый экземпляр потомка TThread - новый
поток выполнения. Множество экземпляров, полученные от класса TThread , делает
C++Builder многопоточным приложением.
программа интерфейс массив поток
__fastcallTMyThread::TMyThread(boolCreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------
// B метод объекта Execute(), вставьте код,
который должен выполняться, когда поток выполняется.
void __fastcallTMyThread::Execute()
{
//---- Place thread code here ----
}
//----------------------------------------------------------------------
Для получения безопасного доступа к управлению
свойствами и методами VCL-объектов в потоке предусмотрен метод Synchronize()
//---------------------------------------------------------------------------__fastcallThreadLenghtLine::Execute()
{= true; // освободить занятую потоком память по
окончании его работы
intColN = N/6;(true){=
0;(FMain->g_BusyEvent[1], INFINITE); //ждёмразрешениенаобработку
ResetEvent(FMain->g_BusyEvent[1]);
//запрещаем переформирование массива(FMain->g_BusyEvent[0]); //запрещаем
переформирование массива
for (int i = 0; i<ColN*6;) { //считаемдлину+=
CalcLengthLine(FMain->A[i++], FMain->A[i++], FMain->A[i++],
FMain->A[i++], FMain->A[i++], FMain->A[i++]);
}++;(Terminated) break; //
прекратитьизвнепоток(&Mon); //блокирует одновременный доступ к компоненту
нескольких потоков
Sleep(T*1000);
}
}
//---------------------------------------------------------------------------__fastcallThreadLenghtLine::Mon()
{>RELenghtLine->Lines->Add(IntToStr(count)
+ ") " + FloatToStr(sum));
SetEvent(FMain->g_BusyEvent[0]); //разрешаем
параллельную обработку(FMain->g_BusyEvent[1]); //разрешаем параллельную
обработку
}
3.2 Синхронизация потоков
Синхронизации потоков основывается на
использовании событий (event). Объект типа событие может принимать одно из двух
состояний: активное или пассивное. Когда событие находится в активном
состоянии, его видят многие потоки одновременно. В результате такой объект
можно использовать для управления работой сразу многих потоков.В библиотеке VCL
события представлены классом TEvent.
Метод CreatEvents():Создает объект класса
TEvent, представляющий объект события.
Метод ResetEvent(): Переводит объект события в
пассивное состояние.
Метод SetEvent() : Переводит объект события в
активное состояние.(): Заставляет ждать, пока другой поток или процесс не
пошлют сигнал об активизации объекта событие.
3.3 Завершение потоков
Потоки могут быть запущены и остановлены сколько
угодно раз в процессе их выполнения. Для временной остановки запущенного потока
можно обратиться к методу потока suspend. Для продолжения выполнения
приостановленного потока вызовите метод потока Resume. Вы можете использовать
вложенные вызовы вышеперечисленных методов, т. к. метод Suspend увеличивает
внутренний счетчик потока, a Resume уменьшает. Поток не будет выполняться до
тех пор, пока счетчик не обратиться в ноль, т. е., если вы вызвали пять раз
метод Suspend, а затем четыре раза Resume, вам понадобится еще один (пятый)
вызов метода Resume для продолжения выполнения потока.
Выполнение потока автоматически завершается
после завершения функции Execute() или закрытии приложения.
Чтобы занятая потоком память освобождалась при
завершении потока надо установитьFreeOnTerminate=false.
4. Листинг программы
ФайлUMain.cpp
#include<vcl.h>
#pragma hdrstop
#include "UMain.h"
#include "UThread1.h"
#include "UThread2.h"
#include "UThread3.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource
"*.dfm"*FMain;*thread1;*thread2;*thread3;
//---------------------------------------------------------------------------
__fastcallTFMain::TFMain(TComponent*
Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------__fastcallTFMain::btnStartClick(TObject
*Sender)
{(eN->Text == "" ||
eT->Text == "" ) {->Panels->Items[0]->Text="Заполнитевсеполя";
}else{->Panels->Items[0]->Text="";->Clear();->Clear();->Clear();_Event[0]
= CreateEvent(NULL, FALSE, FALSE, NULL); //Создаёмсобытие_Event[1]
= CreateEvent(NULL, FALSE, TRUE, NULL); //Создаёмсобытие(g_Event[0]);
//разрешаемформирование(g_Event[1]);
//запрещаемобработки
thread1 = newThreadCreatMassiv(true); //создаем
поток в приостановленном состоянии (true)->N = StrToInt(eN->Text);
//Передача параметров потоку
thread1->T =
StrToInt(eT->Text);
thread1->Resume(); //Возобновляет работу
приостановленного потока
thread2 = new
ThreadMinMax(true);->N = StrToInt(eN->Text);->T = StrToInt(eT->Text);->Resume();=
new ThreadIndex(true);->N = StrToInt(eN->Text);->T =
StrToInt(eT->Text);->Resume();
}
}
//---------------------------------------------------------------------------__fastcallTFMain::btnStopClick(TObject
*Sender)
{->Suspend(); //Приостанавливаетработупотока->Suspend();->Suspend();
//---------------------------------------------------------------------------__fastcallTFMain::btnExitClick(TObject
*Sender)
{>Close();
}
//---------------------------------------------------------------------------
ФайлUThread1.cpp
#include <vcl.h>
#pragma hdrstop
#include "UThread1.h"
#include "UMain.h"
#include "UThread2.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties
of objects in VCL can only be
// used in a method called using
Synchronize, for example:
//
// Synchronize(&UpdateCaption);
//
// where UpdateCaption could look
like:
//
// void
__fastcallThreadCreatMassiv::UpdateCaption()
// {
// Form1->Caption = "Updated
in a thread";
// }
//---------------------------------------------------------------------------
__fastcallThreadCreatMassiv::ThreadCreatMassiv(boolCreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------__fastcallThreadCreatMassiv::Execute()
{= -999;= 999;
FreeOnTerminate = true; // освободить занятую
потоком память по окончании его работы
while (true) {(FMain->g_Event[0],
INFINITE);
ResetEvent(FMain->g_Event[1]); //запрещаем
переформирование массива(FMain->g_Event[0]); //запрещаем переформирование
массива
srand(time(NULL));(int i = 0; i <
N; i++) {>A[i] = rand() % (min - max) + min; //заполняеммассиврандомнымичислами
}++;(Terminated) break; // прекратить из вне
поток(&Sinchr); //блокирует одновременный доступ к компоненту нескольких
потоков
Sleep(T*1000);
}
//---------------------------------------------------------------------------
}__fastcallThreadCreatMassiv::Sinchr()
{;(int i = 0; i < N; i++) {+=
IntToStr(FMain->A[i]) + ", ";
SetEvent(FMain->g_Event[0]); //разрешаем
параллельную обработку(FMain->g_Event[1]); //разрешаем параллельную
обработку
}>reThread1->Lines->Add(IntToStr(count)
+ ") " + rezult); //выводрезультатоввычисления
Файл Thread2.cpp
#include <vcl.h>
#pragma hdrstop
#include "UThread2.h"
#include "UMain.h"
#include "UThread1.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties
of objects in VCL can only be
// used in a method called using
Synchronize, for example:
//
// Synchronize(&UpdateCaption);
//
// where UpdateCaption could look
like:
//
// void
__fastcallThreadSredZnach::UpdateCaption()
// {
// Form1->Caption = "Updated
in a thread";
// }
//---------------------------------------------------------------------------
__fastcallThreadMinMax::ThreadMinMax(boolCreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------__fastcallThreadMinMax::Execute()
{= true; // освободить
занятую
потоком
память
по
окончании
его
работы(true){(FMain->g_Event[1],
INFINITE); //ждёмразрешениенаобработку
ResetEvent(FMain->g_Event[1]); //запрещаем
переформирование массива(FMain->g_Event[0]); //запрещаем переформирование
массива
max = 0;= 0;= FMain->A[0];(int i
= 0; i<N; i++) {(FMain->A[i] < min)
}(FMain->A[i] > max)
{= FMain->A[i];
}
}++;
if(Terminated) break; //
прекратитьизвнепоток(&Sinhr); //блокирует одновременный доступ к компоненту
нескольких потоков
Sleep(T*1000);
}
}
//---------------------------------------------------------------------------__fastcallThreadMinMax::Sinhr()
{>reThread2->Lines->Add(IntToStr(count)
+ ") " + "max = " + max + ", min = " + min); //выводрезультатоввычисления
SetEvent(FMain->g_Event[0]); //разрешаем
параллельную обработку(FMain->g_Event[1]); //разрешаем параллельную
обработку
}
ФайлUThread3.cpp
#include <vcl.h>
#pragma hdrstop
#include "UThread3.h"
#include "UMain.h"
#include "UThread1.h"
#include "UThread2.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties
of objects in VCL can only be
// used in a method called using
Synchronize, for example:
//
// Synchronize(&UpdateCaption);
//
// where UpdateCaption could look
like:
//
// void
__fastcallThreadIndex::UpdateCaption()
// {
// Form1->Caption = "Updated
in a thread";
// }
//---------------------------------------------------------------------------
__fastcallThreadIndex::ThreadIndex(boolCreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------__fastcallThreadIndex::Execute()
{= true; // освободить
занятую
потоком
память
по
окончании
его
работы=
N/3;(true){(FMain->g_Event[1], INFINITE); //ждёмразрешениенаобработку
ResetEvent(FMain->g_Event[1]); //запрещаем
переформирование массива(FMain->g_Event[0]); //запрещаем переформирование
массива
rezult = "";(int i = 0; i
< N; i++){
sum += FMain->A[i];//сумма всех элементов
массива
}= sum/N; // среднее
арифметическое(int i = 0; i < N; i++){
raz = arg - FMain->A[i]; // отклонение
каждого числа
rezult += FloatToStr(raz) + ",
";
}++;(Terminated) break; // прекратить
извне поток
Synchronize(&Sinhr); //блокирует
одновременный доступ к компоненту нескольких потоков
Sleep(T*1000);
}
}
//---------------------------------------------------------------------------__fastcallThreadIndex::Sinhr(){>reThread3->Lines->Add(IntToStr(count)
+ ") " + rezult); //выводрезультатоввычисления
SetEvent(FMain->g_Event[0]); //разрешаем
параллельную обработку(FMain->g_Event[1]); //разрешаем параллельную
обработку
}
Заключение
В процессе работы над курсовым проектом были
изучены основы многопоточного программирования в Windows с использованием
библиотеки визуальных компонентов (VCL) BuilderC++.
) Создание потоков.
) Синхронизация потоков.
) Уничтожение потоков
В результате было разработано многопоточное
приложение которое создает в первом потоке случайный массив А из N целых чисел
в диапазоне от -999 до 999 выводит на экран эти числа.
Во втором потоке определяются минимальные и
максимальные значений.
В третьем потоке вычисляется отклонение всех
чисел среднего арифметического.
Все потоки выводят результаты своей работы в
текстовые поля, каждый поток в свое поле.
Синхронизация потоков осуществлялась на основе
событий.
Список использованной литературы
1. Методические указания к курсовой работе по дисциплине
«ОПЕРАЦИОННЫЕ СИСТЕМЫ» для студентов 3-го курса специальности 230102 АСОИУ/
составитель: к.т.н., доц. В.Н. Цыганенко.
2. Рихтер Дж. Windows для профессионалов. Создание
эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows /
Пер. с англ. - 4-е изд. - СПб.: Питер; М.: Изд-во «Русская редакция»; 2008. -
720.
. А.Я. Архангельский - С++ Builder 6 Книга 1 Язык C++ ..
БИНОМ2002 г.