1
0
mirror of https://github.com/loginov-dmitry/multithread.git synced 2024-11-28 09:33:03 +02:00

Примеры (с 1-го по 8-й) для книги по многопоточному программированию.

This commit is contained in:
loginov-dmitry 2020-06-28 23:47:55 +03:00
parent 5d6700ce26
commit 8b5ad80184
47 changed files with 3914 additions and 0 deletions

View File

@ -0,0 +1,14 @@
program CalcTimeQuant;
uses
Forms,
CalcTimeQuantUnit in 'CalcTimeQuantUnit.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

View File

@ -0,0 +1,72 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{9518bf24-be4a-43be-b4d4-f6878dca152f}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>CalcTimeQuant.exe</DCC_DependencyCheckOutputName>
<MainSource>CalcTimeQuant.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">CalcTimeQuant.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<ItemGroup />
<ItemGroup>
<DelphiCompile Include="CalcTimeQuant.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="CalcTimeQuantUnit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
</Project>

Binary file not shown.

View File

@ -0,0 +1,98 @@
object Form1: TForm1
Left = 0
Top = 0
Caption =
#1055#1088#1086#1075#1088#1072#1084#1084#1072' '#1076#1083#1103' '#1086#1087#1088#1077#1076#1077#1083#1077#1085#1080#1103' '#1076#1083#1080#1090#1077#1083#1100#1085#1086#1089#1090#1080' '#1074#1099#1076#1077#1083#1103#1077#1084#1099#1093' '#1082#1074#1072#1085#1090#1086#1074' '#1074#1088#1077#1084#1077#1085 +
#1080
ClientHeight = 434
ClientWidth = 646
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
DesignSize = (
646
434)
PixelsPerInch = 96
TextHeight = 19
object Label1: TLabel
Left = 8
Top = 8
Width = 607
Height = 95
Caption =
#1044#1083#1103' '#1086#1087#1088#1077#1076#1077#1083#1077#1085#1080#1103' '#1076#1083#1080#1090#1077#1083#1100#1085#1086#1089#1090#1080' '#1082#1074#1072#1085#1090#1072' '#1074#1088#1077#1084#1077#1085#1080', '#1082#1086#1090#1086#1088#1099#1081' '#1074#1099#1076#1077#1083#1103#1077#1090#1089#1103' ' +
#1076#1083#1103' '#1088#1072#1073#1086#1090#1099' '#1087#1086#1090#1086#1082#1086#1074', '#1087#1088#1086#1075#1088#1072#1084#1084#1072' '#1076#1086#1083#1078#1085#1072' '#1088#1072#1073#1086#1090#1072#1090#1100' '#1085#1072' '#1086#1076#1085#1086#1084' '#1103#1076#1088#1077' '#1087#1088#1086#1094 +
#1077#1089#1089#1086#1088#1072'! '#1055#1088#1080#1074#1103#1079#1072#1090#1100' '#1079#1072#1087#1091#1097#1077#1085#1085#1091#1102' '#1087#1088#1086#1075#1088#1072#1084#1084#1091' '#1082' '#1103#1076#1088#1091' '#1084#1086#1078#1085#1086' '#1089' '#1087#1086#1084#1086#1097#1100#1102' '#1076#1080 +
#1089#1087#1077#1090#1095#1077#1088#1072' '#1079#1072#1076#1072#1095' Windows. '#1044#1083#1103' '#1101#1090#1086#1075#1086' '#1085#1072' '#1074#1082#1083#1072#1076#1082#1077' "'#1055#1088#1086#1094#1077#1089#1089#1099'" '#1097#1077#1083#1082#1085#1091#1090#1100 +
' '#1085#1072' '#1087#1088#1086#1094#1077#1089#1089#1077' '#1087#1088#1072#1074#1086#1081' '#1082#1085#1086#1087#1082#1086#1081' '#1084#1099#1096#1080' '#1080' '#1074#1099#1073#1088#1072#1090#1100' '#1087#1091#1085#1082#1090' "'#1047#1072#1076#1072#1090#1100' '#1089#1086#1086#1090#1074#1077#1090 +
#1089#1090#1074#1080#1077'"'
Font.Charset = DEFAULT_CHARSET
Font.Color = clBlue
Font.Height = -16
Font.Name = 'Tahoma'
Font.Style = []
ParentFont = False
WordWrap = True
end
object Label2: TLabel
Left = 32
Top = 136
Width = 146
Height = 19
Caption = #1057#1086#1079#1076#1072#1074#1072#1090#1100' '#1087#1086#1090#1086#1082#1086#1074':'
end
object Label3: TLabel
Left = 16
Top = 176
Width = 90
Height = 19
Caption = #1056#1077#1079#1091#1083#1100#1090#1072#1090#1099':'
end
object edThreadCount: TEdit
Left = 184
Top = 136
Width = 73
Height = 27
TabOrder = 0
Text = '2'
end
object btnStartThreads: TButton
Left = 296
Top = 126
Width = 297
Height = 41
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1086#1090#1086#1082#1080' '#1085#1072' 5 '#1089#1077#1082#1091#1085#1076
TabOrder = 1
OnClick = btnStartThreadsClick
end
object Memo1: TMemo
Left = 8
Top = 201
Width = 630
Height = 225
Anchors = [akLeft, akTop, akRight, akBottom]
ScrollBars = ssVertical
TabOrder = 2
end
object Button1: TButton
Left = 304
Top = 168
Width = 201
Height = 25
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' Sleep-'#1087#1086#1090#1086#1082
TabOrder = 3
OnClick = Button1Click
end
object Timer1: TTimer
Interval = 500
OnTimer = Timer1Timer
Left = 24
Top = 176
end
end

View File

@ -0,0 +1,186 @@
unit CalcTimeQuantUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TCalcQuantThread = class(TThread)
private
// Äîáàâëÿåò äëèòåëüíîñòü èíòåðâàëà àêòèâíîñòè (êâàíò âðåìåíè)
procedure AddToWorkList(WorkTime: Double);
// Äîáàâëÿåò äëèòåëüíîñòü èíòåðâàëà áåçäåéñòâèÿ (â ñïÿùåì ñîñòîÿíèè)
procedure AddToNotWorkList(NotWorkTime: Double);
protected
procedure Execute; override;
public
ThreadNum: Integer; // Íîìåð ïîòîêà
IsFinish: Boolean; // Ôëàã "ðàáîòà ïîòîêà çàâåðøåíà"
WorkAll: Double; // Îáùåå âðåìÿ ðàáîòû
NotWorkAll: Double; // Îáùåå âðåìÿ áåçäåéñòâèÿ
LoopCount: Integer; // Êîëè÷åñòâî öèêëîâ
WorkList: array of Double; // Äëèòåëüíîñòü âûäåëåííûõ êâàíòîâ âðåìåíè
NotWorkList: array of Double; // Äëèòåëüíîñòü èíòåðâàëîâ ïðîñòîÿ
constructor Create(ThreadNum: Integer);
end;
TSleepThread = class(TThread)
protected
procedure Execute; override;
end;
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
edThreadCount: TEdit;
btnStartThreads: TButton;
Label3: TLabel;
Memo1: TMemo;
Timer1: TTimer;
Button1: TButton;
procedure btnStartThreadsClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
FList: TList; // Ñïèñîê çàïóùåííûõ ïîòîêîâ
SleepThread: TSleepThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnStartThreadsClick(Sender: TObject);
var
I: Integer;
begin
Memo1.Clear;
for I := 1 to StrToInt(edThreadCount.Text) do
FList.Add(TCalcQuantThread.Create(I));
btnStartThreads.Enabled := False;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SleepThread := TSleepThread.Create(False);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FList := TList.Create;
DecimalSeparator := '.';
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := 0 to FList.Count - 1 do
TCalcQuantThread(FList[I]).Free;
FList.Free;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
I: Integer;
Q: Double;
T: TCalcQuantThread;
s: string;
begin
for I := FList.Count - 1 downto 0 do
begin
T := TCalcQuantThread(FList[I]);
if T.IsFinish then
begin
s := Format('Èíòåðâàëû àêòèâíîñòè ïîòîêà #%d (Îáùåå âðåìÿ=%f; ×èñëî êâàíòîâ=%d; '+
'×èñëî öèêëîâ=%d): ', [T.ThreadNum, T.WorkAll, Length(T.WorkList), T.LoopCount]);
for Q in T.WorkList do
s := s + FormatFloat('0.0000', Q) + ',';
Memo1.Lines.Add(s);
s := Format('Èíòåðâàëû áåçäåéñòâèÿ ïîòîêà #%d (Îáùåå âðåìÿ=%f; ×èñëî èíòåðâàëîâ '+
'áåçäåéñòâèÿ=%d): ', [T.ThreadNum, T.NotWorkAll, Length(T.NotWorkList)]);
for Q in T.NotWorkList do
s := s + FormatFloat('0.0000', Q) + ',';
Memo1.Lines.Add(s + sLineBreak);
T.Free;
FList.Delete(I);
end;
end;
if FList.Count = 0 then
btnStartThreads.Enabled := True;
end;
{ TCalcQuantThread }
procedure TCalcQuantThread.AddToNotWorkList(NotWorkTime: Double);
begin
SetLength(NotWorkList, Length(NotWorkList) + 1);
NotWorkList[High(NotWorkList)] := NotWorkTime;
NotWorkAll := NotWorkAll + NotWorkTime;
end;
procedure TCalcQuantThread.AddToWorkList(WorkTime: Double);
begin
SetLength(WorkList, Length(WorkList) + 1);
WorkList[High(WorkList)] := WorkTime;
WorkAll := WorkAll + WorkTime;
end;
constructor TCalcQuantThread.Create(ThreadNum: Integer);
begin
inherited Create(False);
Self.ThreadNum := ThreadNum;
end;
procedure TCalcQuantThread.Execute;
var
StartTicks, BreakDiff, QuantDiff, CurQuantTime: Int64;
PrevTicks, CurTicks, CurQuantStart: Int64;
Freq: Int64;
begin
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(StartTicks);
PrevTicks := StartTicks;
CurQuantStart := StartTicks;
BreakDiff := 5 * Freq;
QuantDiff := Round(0.001 * Freq);
CurQuantTime := 0;
repeat
QueryPerformanceCounter(CurTicks);
Inc(LoopCount);
if CurTicks - PrevTicks > QuantDiff then
begin // Åñëè ðàçíèöà îêàçàëàñü áîëüøå 1 ìñ, çíà÷èò ÎÑ ïðèîñòàíàâëèâàëà
// ðàáîòó ïîòîêà è òåïåðü íà÷àëñÿ îòñ÷¸ò íîâîãî êâàíòà
AddToWorkList(CurQuantTime / Freq); // Ñîõðàíÿåì âðåìÿ ðàáîòû ïîòîêà
AddToNotWorkList((CurTicks - PrevTicks) / Freq); // Ñîõðàíÿåì âðåìÿ ïðîñòîÿ ïîòîêà
CurQuantStart := CurTicks;
CurQuantTime := 0;
end else
CurQuantTime := CurTicks - CurQuantStart;
PrevTicks := CurTicks;
until (CurTicks - StartTicks) > BreakDiff;
if CurQuantTime > 0 then // Îáðàáàòûâàåì äëèòåëüíîñòü ïîñëåäíåãî êâàíòà
AddToWorkList(CurQuantTime / Freq);
IsFinish := True;
end;
{ TSleepThread }
procedure TSleepThread.Execute;
begin
while not Terminated do Sleep(1);
end;
end.

413
CommonUtils/MTUtils.pas Normal file
View File

@ -0,0 +1,413 @@
{
Copyright (c) 2020, Loginov Dmitry Sergeevich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
unit MTUtils;
interface
uses
Windows, SysUtils, Classes, Contnrs, SyncObjs, DateUtils, StrUtils, Math;
type
TThreadAccessTerminated = class(TThread);
// Ïîäñêàçêà ñàìîìó ñåáå, ãäå íàõîäèòñÿ TObjectList
TObjectListHelp = class(Contnrs.TObjectList);
{ TPerformance ïðåäíàçíà÷åíà äëÿ òî÷íîãî çàìåðà âðåìåíè,
ïðîøåäøåãî ïîñëå íà÷àëà èçìåðåíèé.
Âíèìàíèå! Èçìåðåíèÿ â ìèêðîñåêóíäàõ
âûïîëíÿþòñÿ ñ ïîãðåøíîñòüþ â íåñêîëüêî ìèêðîñåêóíä (íåñìîòðÿ íà
èñïîëüçîâàíèå ïåðåìåííîé PerformanceIgnoredTicks }
TPerformance = record
private
FStartCounter: Int64;
FIsRunning: Boolean;
FElapsedTicks: Int64;
public
// Íà÷èíàåò çàìåð.
procedure Start;
// Çàâåðøàåò çàìåð. Îáíîâëÿåò ïîëå FElapsedTicks. Ïîñëå òîãî, êàê âûçâàí
// ìåòîä Stop, ìåòîäû ElapsedXXX áóäóò âîçâðàùàòü çàïîìíåííîå â FElapsedTicks çíà÷åíèå
procedure Stop;
// Âîçâðàùàåò êîë-âî ìèëëèñåêóíä ïîñëå íà÷àëà çàìåðîâ
function ElapsedMilliseconds(AStartNew: Boolean = False): Int64;
// Âîçâðàùàåò êîë-âî ìèêðîñåêóíä ïîñëå íà÷àëà çàìåðîâ
function ElapsedMicroseconds(AStartNew: Boolean = False): Int64;
// Âîçâðàùàåò êîë-âî ñåêóíä ïîñëå íà÷àëà çàìåðîâ
function ElapsedSeconds(AStartNew: Boolean = False): Double;
// Âîçâðàùàåò êîëè÷åñòâî òèêîâ ñ íà÷àëà çàìåðîâ
function ElapsedTicks(AStartNew: Boolean = False): Int64;
// Âîçâðàùàåò âðåìÿ (TDateTime), ïðîøåäøåå ñ íà÷àëà çàìåðîâ
function ElapsedTime(AStartNew: Boolean = False): TDateTime;
// Âîçâðàùàåò True, åñëè èçìåðåíèÿ çàïóùåíû
property IsRunning: Boolean read FIsRunning;
end;
TPerformanceEvent = record
// Äàòà/âðåìÿ íà÷àëà è îêîí÷àíèÿ ñîáûòèÿ (ïî ñòàíäàðòíîìó ñèñòåìíîìó òàéìåðó)
BegDateTime: TDateTime;
EndDateTime: TDateTime;
EventName: string; // Íàèìåíîâàíèå ñîáûòèÿ
BegCounter: Int64; // Çíà÷åíèå ñ÷¸ò÷èêà â íà÷àëå ñîáûòèÿ
EndCounter: Int64; // Çíà÷åíèå ñ÷¸ò÷èêà â êîíöå ñîáûòèÿ
function ElapsedTicks: Int64;
function ElapsedMilliseconds: Int64;
function ElapsedMicroseconds: Int64;
function ElapsedSeconds: Double;
procedure Start(AName: string);
procedure Stop;
end;
TGetPerformanceEventsOption = (eoWriteStartTime, eoWriteStopTime, eoWriteAllTime,
eoWriteBegTime, eoWriteEndTime, eoUseMicroSec, eoWriteFromStart);
TGetPerformanceEventsOptions = set of TGetPerformanceEventsOption;
{Ñòðóêòóðà-çàïèñü äëÿ ïðîòîêîëèðîâàíèÿ äëèòåëüíîñòè ñîáûòèé}
TPerformanceEvents = record
Events: array of TPerformanceEvent;
// Çàïóñêàåò èçìåðåíèå íîâîãî ñîáûòèÿ
procedure StartEvent(EventName: string);
// Îñòàíàâëèâàåò èçìåðåíèå ñîáûòèÿ. EventName Âû ìîæåòå óêàçûâàòü
// òîëüêî äëÿ íàãëÿäíîñòè.
procedure StopEvent(EventName: string = '');
// Âîçâðàùàåò èíôîðìàöèþ îá èçìåðåíèè äëèòåëüíîñòè ñîáûòèé
function GetEventsAsString(EvOp: TGetPerformanceEventsOptions): string;
end;
// Ïðîñòîé ïðèìåð îðãàíèçàöèè ïàóçû â ðàáîòå ïîòîêà ñ êîíòðîëåì ñâîéñòâà Terminate
procedure ThreadWaitTimeout(AThread: TThread; ATimeout: Integer);
// Ýìóëÿöèÿ ïîëåçíîé ðàáîòû
procedure EmulateUsefullWork(WorkTime: Integer);
procedure ThreadShowMessageFmt(Msg: string; Args: array of const);
procedure ThreadShowMessage(Msg: string);
var
PerformanceFrequency: Int64;
// Êîëè÷åñòâî òèêîâ, êîòîðûå íóæíî èãíîðèðîâàòü äëÿ áîëåå òî÷íîãî
// èçìåðåíèÿ âðåìåííûõ èíòåðâàëîâ
PerformanceIgnoredTicks: Int64;
StringProtectSection: TCriticalSection;
implementation
procedure ThreadShowMessage(Msg: string);
begin
Windows.MessageBox(0, PChar(Msg), '', MB_OK);
end;
procedure ThreadShowMessageFmt(Msg: string; Args: array of const);
begin
ThreadShowMessage(Format(Msg, Args));
end;
procedure EmulateUsefullWork(WorkTime: Integer);
begin
Sleep(WorkTime);
end;
// Ðåàëèçàöèÿ, îñíîâàííàÿ íà ôóíêöèè GetTickCount
{procedure ThreadWaitTimeout(AThread: TThread; ATimeout: Integer);
var
StartTime, Diff, tc: Cardinal;
T: TThreadAccessTerminated;
begin
// Ïîëó÷àåì äîñòóï ê protected-ñâîéñòâó Terminated
T := TThreadAccessTerminated(AThread);
// Åñëè ïîòîê íóæíî çàâåðøèòü, òî ñðàçó âûõîäèì èç öèêëà
if T.Terminated then Exit;
// Çàïîìèíàåì òåêóùåå âðåìÿ (â ìèëëèñåêóíäàõ îò âêëþ÷åíèÿ êîìïüþòåðà)
StartTime := GetTickCount;
while True do
begin
tc := GetTickCount;
// Ïðåðûâàåì îæèäàíèå, åñëè ôóíêöèÿ GetTickCount íà÷àëà íîâûé êðóã
// èíà÷å íàøà ôóíêöèÿ îæèäàíèÿ ìîæåò çàâèñíóòü
if (tc < StartTime) then Exit;
// Ïðåðûâàåì îæèäàíèå, åñëè ïðåâûñèëè óêàçàííûé òàéìàóò
Diff := tc - StartTime;
if (Diff >= ATimeout) or T.Terminated then
Exit;
// Çàìîðàæèâàåì ïîòîê ïðèìåðíî íà 20 ìñ
Sleep(20);
end;
end; }
// Ðåàëèçàöèÿ, îñíîâàííàÿ íà TPerformance
procedure ThreadWaitTimeout(AThread: TThread; ATimeout: Integer);
var
p: TPerformance;
T: TThreadAccessTerminated;
begin
// Ïîëó÷àåì äîñòóï ê protected-ñâîéñòâó Terminated
T := TThreadAccessTerminated(AThread);
// Åñëè ïîòîê íóæíî çàâåðøèòü, òî ñðàçó âûõîäèì èç öèêëà
if T.Terminated then Exit;
p.Start; // Íà÷èíàåì çàìåð âðåìåíè
while True do
begin
if T.Terminated or (p.ElapsedMilliseconds >= ATimeout) then
Exit;
// Çàìîðàæèâàåì ïîòîê ïðèìåðíî íà 10 ìñ
Sleep(10);
end;
end;
{ TPerformance }
function TPerformance.ElapsedMicroseconds(AStartNew: Boolean = False): Int64;
begin
Result := Round(ElapsedSeconds(AStartNew) * 1000000);
end;
function TPerformance.ElapsedMilliseconds(AStartNew: Boolean = False): Int64;
begin
Result := Round(ElapsedSeconds(AStartNew) * 1000);
end;
function TPerformance.ElapsedSeconds(AStartNew: Boolean = False): Double;
begin
Result := ElapsedTicks(AStartNew) / PerformanceFrequency;
end;
function TPerformance.ElapsedTicks(AStartNew: Boolean = False): Int64;
var
ACounter: Int64;
begin
if FIsRunning then
begin // Åñëè èçìåðåíèÿ çàïóùåíû, òî âîçâðàùàåì òåêóùåå çíà÷åíèå
QueryPerformanceCounter(ACounter);
Result := ACounter - FStartCounter - PerformanceIgnoredTicks;
if Result < 0 then
Result := 0;
end else
begin // Èçìåðåíèÿ îñòàíîâëåíû - âîçâðàùàåì çíà÷åíèå íà ìîìåíò îñòàíîâà
Result := FElapsedTicks
end;
if AStartNew then
Start;
end;
function TPerformance.ElapsedTime(AStartNew: Boolean): TDateTime;
begin
Result := IncMilliSecond(0, ElapsedMilliseconds(AStartNew));
end;
procedure TPerformance.Start;
begin
FIsRunning := True;
FElapsedTicks := 0;
// Çàïðàøèâàåì ñ÷¸ò÷èê â ñàìîì êîíöå ìåòîäà
QueryPerformanceCounter(FStartCounter);
end;
procedure TPerformance.Stop;
var
ACounter: Int64;
begin
// Çàïðàøèâàåì ñ÷¸ò÷èê â ñàìîì íà÷àëå ìåòîäà
QueryPerformanceCounter(ACounter);
FIsRunning := False;
FElapsedTicks := ACounter - FStartCounter - PerformanceIgnoredTicks;
if FElapsedTicks < 0 then
FElapsedTicks := 0;
end;
{ TPerformanceEvent }
function TPerformanceEvent.ElapsedMilliseconds: Int64;
begin
Result := Round(ElapsedSeconds * 1000);
end;
function TPerformanceEvent.ElapsedMicroseconds: Int64;
begin
Result := Round(ElapsedSeconds * 1000000);
end;
function TPerformanceEvent.ElapsedSeconds: Double;
begin
Result := ElapsedTicks / PerformanceFrequency;
end;
function TPerformanceEvent.ElapsedTicks: Int64;
begin
Result := EndCounter - BegCounter;
end;
procedure TPerformanceEvent.Start(AName: string);
begin
BegDateTime := Now;
EventName := AName;
QueryPerformanceCounter(BegCounter);
end;
procedure TPerformanceEvent.Stop;
begin
QueryPerformanceCounter(EndCounter);
EndCounter := EndCounter - PerformanceIgnoredTicks;
if EndCounter < BegCounter then
EndCounter := BegCounter;
EndDateTime := Now;
end;
{ TPerformanceEvents }
function TPerformanceEvents.GetEventsAsString(
EvOp: TGetPerformanceEventsOptions): string;
var
Ev, EvFirst: TPerformanceEvent;
s: string;
I: Integer;
AllTime, AllTicks: Int64;
Sec: Double;
begin
Result := '';
if Length(Events) = 0 then
begin
Result := 'Events array is empty';
Exit;
end;
EvFirst := Events[0];
if eoWriteStartTime in EvOp then
begin
Result := 'StartTime: ' + FormatDateTime('dd.mm.yy hh:nn:ss.zzz', EvFirst.BegDateTime);
if eoWriteAllTime in EvOp then
Result := Result + '; ';
end;
if eoWriteAllTime in EvOp then
begin
Result := Result + 'AllTime: ';
AllTicks := 0;
for Ev in Events do
AllTicks := AllTicks + Ev.ElapsedTicks;
Sec := AllTicks / PerformanceFrequency;
if eoUseMicroSec in EvOp then
AllTime := Round(Sec * 1000000)
else
AllTime := Round(Sec * 1000);
Result := Result + IntToStr(AllTime) + IfThen(eoUseMicroSec in EvOp, ' us', ' ms') + '; ';
end;
for I := 0 to High(Events) do
begin
Ev := Events[I];
Result := Result + Ev.EventName + ':[';
if eoUseMicroSec in EvOp then
s := IntToStr(Ev.ElapsedMicroseconds) + ' us'
else
s := IntToStr(Ev.ElapsedMilliseconds) + ' ms';
if eoWriteBegTime in EvOp then
s := s + '; BegTime: ' + FormatDateTime('dd.mm.yy hh:nn:ss.zzz', Ev.BegDateTime);
if eoWriteEndTime in EvOp then
s := s + '; EndTime: ' + FormatDateTime('dd.mm.yy hh:nn:ss.zzz', Ev.EndDateTime);
if eoWriteFromStart in EvOp then
begin
s := s + '; FromStart: ';
AllTicks := Ev.EndCounter - EvFirst.BegCounter;
Sec := AllTicks / PerformanceFrequency;
if eoUseMicroSec in EvOp then
AllTime := Round(Sec * 1000000)
else
AllTime := Round(Sec * 1000);
s := s + IntToStr(AllTime) + IfThen(eoUseMicroSec in EvOp, ' us', ' ms');
end;
Result := Result + s + ']';
if I < High(Events) then
Result := Result + '; ';
end;
end;
procedure TPerformanceEvents.StartEvent(EventName: string);
var
Cnt: Integer;
begin
Cnt := Length(Events);
if (Cnt > 0) and (Events[Cnt - 1].EndCounter = 0) then
StopEvent();
SetLength(Events, Cnt + 1);
Events[Cnt].Start(EventName);
end;
procedure TPerformanceEvents.StopEvent(EventName: string = '');
var
Idx: Integer;
begin
Idx := High(Events);
if Idx >= 0 then
Events[Idx].Stop;
end;
procedure CalcIgnoredPerformanceTicks;
var
p1, p2: Int64;
begin
QueryPerformanceCounter(p1);
QueryPerformanceCounter(p2);
PerformanceIgnoredTicks := p2 - p1;
// Åñëè Âàì íå òðåáóåòñÿ êîððåêòèðîâêà, òî äîñòàòî÷íî ïðèñâîèòü:
// PerformanceIgnoredTicks := 0
end;
initialization
// Ïîëó÷àåì ÷àñòîòó âûñîêî÷àñòîòíîãî òàéìåðà
QueryPerformanceFrequency(PerformanceFrequency);
if PerformanceFrequency = 0 then
PerformanceFrequency := 1; // ×òîáû íå áûëî îøèáêè äåëåíèÿ íà íîëü
CalcIgnoredPerformanceTicks;
// Êðèòè÷åñêàÿ ñåêöèÿ äëÿ çàùèòû ñòðîê îò
// îäíîâðåìåííîãî äîñòóïà èç ðàçíûõ ïîòîêîâ
StringProtectSection := TCriticalSection.Create;
finalization
StringProtectSection.Free;
end.

File diff suppressed because it is too large Load Diff

14
Ex1/Ex1Proj.dpr Normal file
View File

@ -0,0 +1,14 @@
program Ex1Proj;
uses
Forms,
Ex1Unit in 'Ex1Unit.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

72
Ex1/Ex1Proj.dproj Normal file
View File

@ -0,0 +1,72 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{e7f0b4a2-d42e-483e-9256-d16113fd41c0}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex1Proj.exe</DCC_DependencyCheckOutputName>
<MainSource>Ex1Proj.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex1Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<ItemGroup />
<ItemGroup>
<DelphiCompile Include="Ex1Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Ex1Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
</Project>

BIN
Ex1/Ex1Proj.res Normal file

Binary file not shown.

34
Ex1/Ex1Unit.dfm Normal file
View File

@ -0,0 +1,34 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 16
object btnRunInParallelThread: TButton
Left = 8
Top = 64
Width = 235
Height = 33
Caption = #1042#1099#1087#1086#1083#1085#1080#1090#1100' '#1074' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1086#1084' '#1087#1086#1090#1086#1082#1077
TabOrder = 0
OnClick = btnRunInParallelThreadClick
end
object btnRunInMainThread: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1042#1099#1087#1086#1083#1085#1080#1090#1100' '#1074' '#1075#1083#1072#1074#1085#1086#1084' '#1087#1086#1090#1086#1082#1077
TabOrder = 1
OnClick = btnRunInMainThreadClick
end
end

73
Ex1/Ex1Unit.pas Normal file
View File

@ -0,0 +1,73 @@
unit Ex1Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyThread = class(TThread)
public
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunInParallelThread: TButton;
btnRunInMainThread: TButton;
procedure btnRunInParallelThreadClick(Sender: TObject);
procedure btnRunInMainThreadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function DoLongCalculations: Int64;
var
I: Integer;
begin
Result := 0;
// Î÷åíü äëèííûé öèêë. Èìèòèðóåò äëèòåëüíûå âû÷èñëåíèÿ.
for I := 1 to MaxInt do
Result := Result + Random(1000);
end;
procedure MyShowMessage(Msg: string);
begin
Windows.MessageBox(0, PChar(Msg), '', MB_OK);
end;
procedure TForm1.btnRunInParallelThreadClick(Sender: TObject);
begin
// Çàïóñêàåò ïàðàëëåëüíûé ïîòîê
TMyThread.Create(False);
end;
{ TMyThread }
procedure TMyThread.Execute;
var
V: Int64;
begin
FreeOnTerminate := True;
V := DoLongCalculations;
MyShowMessage('Ðåçóëüòàò: ' + IntToStr(V));
end;
procedure TForm1.btnRunInMainThreadClick(Sender: TObject);
var
V: Int64;
begin
V := DoLongCalculations;
MyShowMessage('Ðåçóëüòàò: ' + IntToStr(V));
end;
end.

14
Ex2/Ex2Proj.dpr Normal file
View File

@ -0,0 +1,14 @@
program Ex2Proj;
uses
Forms,
Ex2Unit in 'Ex2Unit.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

36
Ex2/Ex2Proj.dproj Normal file
View File

@ -0,0 +1,36 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{e7f0b4a2-d42e-483e-9256-d16113fd41c0}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex2Proj.exe</DCC_DependencyCheckOutputName>
<MainSource>Ex2Proj.dpr</MainSource>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType />
<BorlandProject>
<BorlandProject><Delphi.Personality><Parameters><Parameters Name="UseLauncher">False</Parameters><Parameters Name="LoadAllSymbols">True</Parameters><Parameters Name="LoadUnspecifiedSymbols">False</Parameters></Parameters><VersionInfo><VersionInfo Name="IncludeVerInfo">False</VersionInfo><VersionInfo Name="AutoIncBuild">False</VersionInfo><VersionInfo Name="MajorVer">1</VersionInfo><VersionInfo Name="MinorVer">0</VersionInfo><VersionInfo Name="Release">0</VersionInfo><VersionInfo Name="Build">0</VersionInfo><VersionInfo Name="Debug">False</VersionInfo><VersionInfo Name="PreRelease">False</VersionInfo><VersionInfo Name="Special">False</VersionInfo><VersionInfo Name="Private">False</VersionInfo><VersionInfo Name="DLL">False</VersionInfo><VersionInfo Name="Locale">1049</VersionInfo><VersionInfo Name="CodePage">1251</VersionInfo></VersionInfo><VersionInfoKeys><VersionInfoKeys Name="CompanyName"></VersionInfoKeys><VersionInfoKeys Name="FileDescription"></VersionInfoKeys><VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="InternalName"></VersionInfoKeys><VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys><VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys><VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys><VersionInfoKeys Name="ProductName"></VersionInfoKeys><VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys><VersionInfoKeys Name="Comments"></VersionInfoKeys></VersionInfoKeys><Source><Source Name="MainSource">Ex2Proj.dpr</Source></Source></Delphi.Personality></BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="Ex2Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Ex2Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
</Project>

BIN
Ex2/Ex2Proj.res Normal file

Binary file not shown.

26
Ex2/Ex2Unit.dfm Normal file
View File

@ -0,0 +1,26 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 16
object btnRunParallelThread: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1099#1081' '#1087#1086#1090#1086#1082
TabOrder = 0
OnClick = btnRunParallelThreadClick
end
end

75
Ex2/Ex2Unit.pas Normal file
View File

@ -0,0 +1,75 @@
unit Ex2Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyLongThread = class(TThread)
private
procedure DoUsefullTask; // Ïðîöåäóðà äëÿ èìèòàöèè ïîëåçíîé ðàáîòû
public
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunParallelThread: TButton;
procedure btnRunParallelThreadClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
MyThread: TMyLongThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunParallelThreadClick(Sender: TObject);
begin
// Çàïóñêàåò ïàðàëëåëüíûé ïîòîê
if MyThread = nil then
MyThread := TMyLongThread.Create(False)
else
raise Exception.Create('Äîïîëíèòåëüíûé ïîòîê óæå çàïóùåí!');
end;
{ TMyLongThread }
procedure TMyLongThread.DoUsefullTask;
begin
// Ðåàëüíûé ïîòîê ìîæåò âûïîëíÿòü êàêóþ óãîäíî ïîëåçíóþ ðàáîòó
//  ó÷åáíûõ öåëÿõ äåëàåì ïàóçó 5 ñåêóíä äëÿ èìèòàöèè çàäåðæêè, êîòîðàÿ
// ìîæåò âîçíèêíóòü ïðè âûïîëíåíèè ïîëåçíîé ðàáîòû
Sleep(5000);
end;
procedure TMyLongThread.Execute;
procedure WaitTimeout(ATimeOut: Integer);
begin
Sleep(ATimeOut);
end;
begin
while not Terminated do
begin
DoUsefullTask;
WaitTimeout(10000); // Îæèäàåì òàéìàóò 10 ñåê.
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// Ïðè çàêðûòèè ïðîãðàììû íåîáõîäèìî çàâåðøèòü ðàáîòó ïîòîêà
// è óíè÷òîæèòü îáúåêò ïîòîêà MyThread
if MyThread <> nil then
MyThread.Free;
end;
end.

15
Ex3/Ex3Proj.dpr Normal file
View File

@ -0,0 +1,15 @@
program Ex3Proj;
uses
Forms,
Ex3Unit in 'Ex3Unit.pas' {Form1},
ProgressViewer in '..\CommonUtils\ProgressViewer.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

72
Ex3/Ex3Proj.dproj Normal file
View File

@ -0,0 +1,72 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{3411b57f-8f9b-461f-805d-57413b36e169}</ProjectGuid>
<MainSource>Ex3Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex3Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex3Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="Ex3Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\CommonUtils\ProgressViewer.pas" />
<DCCReference Include="Ex3Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
</Project>

BIN
Ex3/Ex3Proj.res Normal file

Binary file not shown.

26
Ex3/Ex3Unit.dfm Normal file
View File

@ -0,0 +1,26 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 16
object btnRunParallelThread: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1099#1081' '#1087#1086#1090#1086#1082
TabOrder = 0
OnClick = btnRunParallelThreadClick
end
end

71
Ex3/Ex3Unit.pas Normal file
View File

@ -0,0 +1,71 @@
unit Ex3Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ProgressViewer;
type
TMyShortThread = class(TThread)
private
procedure DoUsefullTask; // Ïðîöåäóðà äëÿ èìèòàöèè ïîëåçíîé ðàáîòû
public
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunParallelThread: TButton;
procedure btnRunParallelThreadClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
MyThread: TMyShortThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunParallelThreadClick(Sender: TObject);
begin
// Çàïóñêàåò ïàðàëëåëüíûé ïîòîê. Åñëè îáúåêò ïîòîêà óæå ñîçäàí,
// òî óíè÷òîæàåò åãî.
if MyThread <> nil then
FreeAndNil(MyThread);
MyThread := TMyShortThread.Create(False);
end;
{ TMyShortThread }
procedure TMyShortThread.DoUsefullTask;
var
AProgress: TProgressViewer;
begin
// Ðåàëüíûé ïîòîê ìîæåò âûïîëíÿòü êàêóþ óãîäíî ïîëåçíóþ ðàáîòó
//  ó÷åáíûõ öåëÿõ äåëàåì ïàóçó 5 ñåêóíä äëÿ èìèòàöèè çàäåðæêè, êîòîðàÿ
// ìîæåò âîçíèêíóòü ïðè âûïîëíåíèè ïîëåçíîé ðàáîòû
AProgress := TProgressViewer.Create('Âûïîëíÿåòñÿ ïîòîê TMyShortThread');
Sleep(5000);
AProgress.TerminateProgress;
end;
procedure TMyShortThread.Execute;
begin
DoUsefullTask;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
// Ïðè çàêðûòèè ïðîãðàììû íåîáõîäèìî çàâåðøèòü ðàáîòó ïîòîêà
// è óíè÷òîæèòü îáúåêò ïîòîêà MyThread
if MyThread <> nil then
MyThread.Free;
end;
end.

14
Ex4/Ex4Proj.dpr Normal file
View File

@ -0,0 +1,14 @@
program Ex4Proj;
uses
Forms,
Ex4Unit in 'Ex4Unit.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

72
Ex4/Ex4Proj.dproj Normal file
View File

@ -0,0 +1,72 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{f16ecf60-c99d-4eaf-b37a-07ee717fb29b}</ProjectGuid>
<MainSource>Ex4Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex4Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex4Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<ItemGroup />
<ItemGroup>
<DelphiCompile Include="Ex4Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Ex4Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
</Project>

BIN
Ex4/Ex4Proj.res Normal file

Binary file not shown.

47
Ex4/Ex4Unit.dfm Normal file
View File

@ -0,0 +1,47 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 16
object Label1: TLabel
Left = 16
Top = 48
Width = 218
Height = 16
Caption = #1056#1077#1078#1080#1084' '#1079#1072#1074#1077#1088#1096#1077#1085#1080#1103' '#1088#1072#1073#1086#1090#1099' '#1087#1086#1090#1086#1082#1086#1074':'
end
object btnRunParallelThreads: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1099#1077' '#1087#1086#1090#1086#1082#1080
TabOrder = 0
OnClick = btnRunParallelThreadsClick
end
object cbTerminateMode: TComboBox
Left = 24
Top = 72
Width = 210
Height = 24
Style = csDropDownList
ItemHeight = 16
ItemIndex = 0
TabOrder = 1
Text = #1055#1086#1089#1083#1077#1076#1086#1074#1072#1090#1077#1083#1100#1085#1086' ('#1084#1077#1076#1083#1077#1085#1085#1086')'
Items.Strings = (
#1055#1086#1089#1083#1077#1076#1086#1074#1072#1090#1077#1083#1100#1085#1086' ('#1084#1077#1076#1083#1077#1085#1085#1086')'
#1054#1076#1085#1086#1074#1088#1077#1084#1077#1085#1085#1086' ('#1073#1099#1089#1090#1088#1077#1077')')
end
end

123
Ex4/Ex4Unit.pas Normal file
View File

@ -0,0 +1,123 @@
unit Ex4Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ProgressViewer;
type
TMyLongThread = class(TThread)
private
FTaskNum: Integer;
procedure DoUsefullTask1; // Ïåðâàÿ çàäà÷à
procedure DoUsefullTask2; // Âòîðàÿ çàäà÷à
procedure DoFinalizeTask; // Çàäà÷à çàïóñêàåòñÿ ïðè çàâåðøåíèè ðàáîòû ïîòîêà
public
constructor Create(TaskNum: Integer);
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunParallelThreads: TButton;
Label1: TLabel;
cbTerminateMode: TComboBox;
procedure btnRunParallelThreadsClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
MyThread1: TMyLongThread; // Ïîòîê äëÿ ïåðâîé çàäà÷è
MyThread2: TMyLongThread; // Ïîòîê äëÿ âòîðîé çàäà÷è
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunParallelThreadsClick(Sender: TObject);
begin
// Çàïóñêàåò ïàðàëëåëüíûé ïîòîê äëÿ çàäà÷è 1
if MyThread1 = nil then
MyThread1 := TMyLongThread.Create(1);
// Çàïóñêàåò ïàðàëëåëüíûé ïîòîê äëÿ çàäà÷è 2
if MyThread2 = nil then
MyThread2 := TMyLongThread.Create(2);
end;
{ TMyLongThread }
constructor TMyLongThread.Create(TaskNum: Integer);
begin
inherited Create(False); // Âûçûâàåì ðîäèòåëüñêèé êîíñòðóêòîð
// Çàïîìèíàåì ïàðàìåòð TaskNum. Îí íóæåí â ìåòîäå Execute
FTaskNum := TaskNum;
end;
procedure TMyLongThread.DoFinalizeTask;
begin
Sleep(5000); // Äàííàÿ óñëîâíàÿ çàäà÷à çàíèìàåò 5 ñåêóíä
end;
procedure TMyLongThread.DoUsefullTask1;
begin
Sleep(1000); // Äàííàÿ óñëîâíàÿ çàäà÷à çàíèìàåò 1 ñåêóíäó
end;
procedure TMyLongThread.DoUsefullTask2;
begin
Sleep(2000); // Äàííàÿ óñëîâíàÿ çàäà÷à çàíèìàåò 2 ñåêóíäû
end;
procedure TMyLongThread.Execute;
procedure WaitTimeout(ATimeOut: Integer);
begin
Sleep(ATimeOut);
end;
begin
while True do
begin
if Terminated then
begin
DoFinalizeTask; // Íåêîòîðûå äåéñòâèÿ ïðè çàâåðøåíèè ïîòîêà
Exit; // Çàâåðøàåì ðàáîòó ïîòîêà
end else
begin
if FTaskNum = 1 then
DoUsefullTask1 // Çàïóñêàåì çàäà÷ó 1
else
DoUsefullTask2; // Çàïóñêàåì çàäà÷ó 2
if not Terminated then // Äîïîëíèòåëüíàÿ ïðîâåðêà íå ïîâðåäèò!
WaitTimeout(1000); // Îæèäàåì òàéìàóò 1 ñåê
end;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
AProgress: TProgressViewer;
begin
AProgress := TProgressViewer.Create('Âûõîä èç ïðîãðàììû');
try
if cbTerminateMode.ItemIndex = 1 then
begin // Âûáðàí ðåæèì "Îäíîâðåìåííî (áûñòðåå)"
if Assigned(MyThread1) then
MyThread1.Terminate; // Âûñòàâëÿåì ôëàã Terminated
if Assigned(MyThread2) then
MyThread2.Terminate; // Âûñòàâëÿåì ôëàã Terminated
end;
MyThread1.Free;
MyThread2.Free;
finally
AProgress.TerminateProgress;
end;
end;
end.

15
Ex5/Ex5Proj.dpr Normal file
View File

@ -0,0 +1,15 @@
program Ex5Proj;
uses
Forms,
Ex5Unit in 'Ex5Unit.pas' {Form1},
MTUtils in '..\CommonUtils\MTUtils.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

72
Ex5/Ex5Proj.dproj Normal file
View File

@ -0,0 +1,72 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{5a439af1-90ce-4391-8632-091e44023bf2}</ProjectGuid>
<MainSource>Ex5Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex5Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex5Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="Ex5Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\CommonUtils\MTUtils.pas" />
<DCCReference Include="Ex5Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
</Project>

BIN
Ex5/Ex5Proj.res Normal file

Binary file not shown.

48
Ex5/Ex5Unit.dfm Normal file
View File

@ -0,0 +1,48 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 16
object Label1: TLabel
Left = 16
Top = 48
Width = 218
Height = 16
Caption = #1056#1077#1078#1080#1084' '#1079#1072#1074#1077#1088#1096#1077#1085#1080#1103' '#1088#1072#1073#1086#1090#1099' '#1087#1086#1090#1086#1082#1086#1074':'
end
object btnRunParallelThreads: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1099#1077' '#1087#1086#1090#1086#1082#1080
TabOrder = 0
OnClick = btnRunParallelThreadsClick
end
object cbTerminateMode: TComboBox
Left = 24
Top = 72
Width = 210
Height = 24
Style = csDropDownList
ItemHeight = 16
ItemIndex = 0
TabOrder = 1
Text = #1055#1086#1089#1083#1077#1076#1086#1074#1072#1090#1077#1083#1100#1085#1086' ('#1084#1077#1076#1083#1077#1085#1085#1086')'
Items.Strings = (
#1055#1086#1089#1083#1077#1076#1086#1074#1072#1090#1077#1083#1100#1085#1086' ('#1084#1077#1076#1083#1077#1085#1085#1086')'
#1054#1076#1085#1086#1074#1088#1077#1084#1077#1085#1085#1086' ('#1073#1099#1089#1090#1088#1077#1077')')
end
end

155
Ex5/Ex5Unit.pas Normal file
View File

@ -0,0 +1,155 @@
unit Ex5Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ProgressViewer, Contnrs, MTUtils;
type
TMyLongThread1 = class(TThread)
private
FUsefullTaskTime: Integer;
public
constructor Create(UsefullTaskTime: Integer);
procedure Execute; override;
end;
TMyLongThread2 = class(TThread)
public
procedure Execute; override;
end;
TMyLongThread3 = class(TThread)
private
FUsefullTaskTime: Integer;
public
constructor Create(UsefullTaskTime: Integer);
procedure Execute; override;
end;
TMyLongThread4 = class(TThread)
public
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunParallelThreads: TButton;
Label1: TLabel;
cbTerminateMode: TComboBox;
procedure btnRunParallelThreadsClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
FList: TObjectList; // Ïîòîêè äëÿ ïåðâîé è âòîðîé çàäà÷è
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunParallelThreadsClick(Sender: TObject);
begin
// Çàïóñêàåì 4 ïàðàëëåëüíûõ ïîòîêà
if FList.Count = 0 then
begin
FList.Add(TMyLongThread1.Create(1000));
FList.Add(TMyLongThread2.Create(False));
FList.Add(TMyLongThread3.Create(2000));
FList.Add(TMyLongThread4.Create(False));
end;
end;
{ TMyLongThread }
constructor TMyLongThread1.Create(UsefullTaskTime: Integer);
begin
inherited Create(False); // Âûçûâàåì ðîäèòåëüñêèé êîíñòðóêòîð
FUsefullTaskTime := UsefullTaskTime;
end;
procedure TMyLongThread1.Execute;
begin
while not Terminated do
begin
EmulateUsefullWork(FUsefullTaskTime);
ThreadWaitTimeout(Self, 60000); // Îæèäàåì òàéìàóò 60 ñåê
end;
Sleep(5000); // Îñòàâëåíî äëÿ äåìîíñòðàöèè ðåæèìà "Îäíîâðåìåííî"
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FList := TObjectList.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
AProgress: TProgressViewer;
I: Integer;
begin
AProgress := TProgressViewer.Create('Âûõîä èç ïðîãðàììû');
try
if cbTerminateMode.ItemIndex = 1 then
begin // Âûáðàí ðåæèì "Îäíîâðåìåííî (áûñòðåå)"
// Âûñòàâëÿåì ôëàã Terminated äëÿ âñåõ ïîòîêîâ. Ìîæíî èñïîëüçîâàòü
// ðîäèòåëüñêèé êëàññ TThread äëÿ îïåðàöèè ïðèâåäåíèÿ òèïîâ.
for I := 0 to FList.Count - 1 do
TThread(FList[I]).Terminate;
end;
// Ïðè óíè÷òîæåíèè ñïèñêà TObjectList áóäóò óíè÷òîæåíû âñå îáúåêòû ïîòîêîâ
FList.Free;
finally
AProgress.TerminateProgress;
end;
end;
{ TMyLongThread2 }
procedure TMyLongThread2.Execute;
begin
while not Terminated do
begin
EmulateUsefullWork(2000);
ThreadWaitTimeout(Self, 60000); // Îæèäàåì òàéìàóò 60 ñåê
end;
Sleep(5000); // Îñòàâëåíî äëÿ äåìîíñòðàöèè ðåæèìà "Îäíîâðåìåííî"
end;
{ TMyLongThread3 }
constructor TMyLongThread3.Create(UsefullTaskTime: Integer);
begin
inherited Create(False);
FUsefullTaskTime := UsefullTaskTime;
end;
procedure TMyLongThread3.Execute;
begin
while not Terminated do
begin
EmulateUsefullWork(FUsefullTaskTime);
ThreadWaitTimeout(Self, 60000); // Îæèäàåì òàéìàóò 60 ñåê
end;
Sleep(5000); // Îñòàâëåíî äëÿ äåìîíñòðàöèè ðåæèìà "Îäíîâðåìåííî"
end;
{ TMyLongThread4 }
procedure TMyLongThread4.Execute;
begin
while not Terminated do
begin
EmulateUsefullWork(1000);
ThreadWaitTimeout(Self, 60000); // Îæèäàåì òàéìàóò 60 ñåê
end;
Sleep(5000); // Îñòàâëåíî äëÿ äåìîíñòðàöèè ðåæèìà "Îäíîâðåìåííî"
end;
end.

14
Ex6/Ex6Proj.dpr Normal file
View File

@ -0,0 +1,14 @@
program Ex6Proj;
uses
Forms,
Ex6Unit in 'Ex6Unit.pas' {Form1};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

76
Ex6/Ex6Proj.dproj Normal file
View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{bcd98240-1abe-47d3-b2bc-bfa99f5070ae}</ProjectGuid>
<MainSource>Ex6Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex6Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
<DCC_UnitSearchPath>..\CommonUtils</DCC_UnitSearchPath>
<DCC_ResourcePath>..\CommonUtils</DCC_ResourcePath>
<DCC_ObjPath>..\CommonUtils</DCC_ObjPath>
<DCC_IncludePath>..\CommonUtils</DCC_IncludePath>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex6Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="Ex6Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="Ex6Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
</Project>

BIN
Ex6/Ex6Proj.res Normal file

Binary file not shown.

26
Ex6/Ex6Unit.dfm Normal file
View File

@ -0,0 +1,26 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 251
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 16
object btnRunInParallelThread: TButton
Left = 8
Top = 8
Width = 235
Height = 33
Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100' '#1087#1072#1088#1072#1083#1083#1077#1083#1100#1085#1099#1081' '#1087#1086#1090#1086#1082
TabOrder = 0
OnClick = btnRunInParallelThreadClick
end
end

95
Ex6/Ex6Unit.pas Normal file
View File

@ -0,0 +1,95 @@
unit Ex6Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ProgressViewer, MTUtils;
type
TMyThread = class(TThread)
private
FThreadNum: Integer;
public
procedure Execute; override;
constructor Create;
destructor Destroy; override;
end;
TForm1 = class(TForm)
btnRunInParallelThread: TButton;
procedure btnRunInParallelThreadClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ThreadCount: Integer;
StopThreadsFlag: Boolean;
implementation
{$R *.dfm}
procedure TForm1.btnRunInParallelThreadClick(Sender: TObject);
begin
// Çàïóñêàåì ïàðàëëåëüíûé ïîòîê
TMyThread.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
pv: TProgressViewer;
begin
// Âûñòàâëÿåì ôëàã StopThreadsFlag, ÷òîáû âñå ïîòîêè çàâåðøèëèñü
StopThreadsFlag := True;
// Çàäåðæèâàåì âûõîä èç ïðîãðàììû, ïîêà íå áóäóò çàâåðøåíû âñå ïîòîêè
if ThreadCount > 0 then
begin
pv := TProgressViewer.Create('Îæèäàåì çàâåðøåíèå ïîòîêîâ');
while ThreadCount > 0 do
Sleep(10);
pv.TerminateProgress;
end;
end;
{ TMyThread }
constructor TMyThread.Create;
begin
inherited Create(False);
// Óâåëè÷èâàåì ãëîáàëüíóþ ïåðåìåííóþ ThreadCount íà 1 è çàïîìèíàåì
// ïîëó÷åííîå çíà÷åíèå
FThreadNum := InterlockedIncrement(ThreadCount);
end;
destructor TMyThread.Destroy;
begin
inherited;
// Óìåíüøàåì ãëîáàëüíóþ ïåðåìåííóþ ThreadCount íà 1
InterlockedDecrement(ThreadCount);
end;
procedure TMyThread.Execute;
var
perf: TPerformance;
begin
FreeOnTerminate := True;
// Îðãàíèçóåì ïàóçó 10 ñåêóíä. Ïðè ýòîì êàæäûå 20 ìñ ïðîâåðÿåì ôëàã StopThreadsFlag
perf.Start;
while perf.SecondSince(False) < 10 do
begin
// Çàêàí÷èâàåì îæèäàíèå, åñëè âûñòàâëåí ôëàã StopThreadsFlag
if StopThreadsFlag then Break;
Sleep(20);
end;
ThreadShowMessageFmt('Ðàáîòà ïîòîêà #%d çàâåðøåíà!', [FThreadNum]);
end;
end.

15
Ex7/Ex7Proj.dpr Normal file
View File

@ -0,0 +1,15 @@
program Ex7Proj;
uses
Forms,
Ex7Unit in 'Ex7Unit.pas' {Form1},
MTUtils in '..\CommonUtils\MTUtils.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

73
Ex7/Ex7Proj.dproj Normal file
View File

@ -0,0 +1,73 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{fb1313c6-5f1a-4359-b086-e66e7d93a42d}</ProjectGuid>
<MainSource>Ex7Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex7Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex7Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<ItemGroup />
<ItemGroup>
<DelphiCompile Include="Ex7Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\CommonUtils\MTUtils.pas" />
<DCCReference Include="Ex7Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
</Project>

BIN
Ex7/Ex7Proj.res Normal file

Binary file not shown.

60
Ex7/Ex7Unit.dfm Normal file
View File

@ -0,0 +1,60 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 127
ClientWidth = 452
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
DesignSize = (
452
127)
PixelsPerInch = 96
TextHeight = 16
object Label1: TLabel
Left = 8
Top = 72
Width = 64
Height = 16
Caption = #1056#1077#1079#1091#1083#1100#1090#1072#1090':'
end
object labResult: TLabel
Left = 78
Top = 72
Width = 7
Height = 16
Caption = '0'
end
object btnRunInParallelThread: TButton
Left = 8
Top = 8
Width = 217
Height = 33
Caption = #1042#1099#1095#1080#1089#1083#1080#1090#1100' '#1089#1091#1084#1084#1091' '#1088#1103#1076#1072' '#1095#1080#1089#1077#1083' '#1076#1086':'
TabOrder = 0
OnClick = btnRunInParallelThreadClick
end
object ProgressBar1: TProgressBar
Left = 8
Top = 49
Width = 436
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
ExplicitWidth = 519
end
object edMaxValue: TEdit
Left = 232
Top = 16
Width = 89
Height = 24
TabOrder = 2
Text = '100000000'
end
end

109
Ex7/Ex7Unit.pas Normal file
View File

@ -0,0 +1,109 @@
unit Ex7Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MTUtils, ComCtrls;
type
TMyThread = class(TThread)
private
FResult: Int64;
FCurrValue: Integer;
procedure SetProgressParams;
procedure SetProgressCurrValue;
public
MaxValue: Integer;
procedure Execute; override;
end;
TForm1 = class(TForm)
btnRunInParallelThread: TButton;
ProgressBar1: TProgressBar;
Label1: TLabel;
labResult: TLabel;
edMaxValue: TEdit;
procedure btnRunInParallelThreadClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FMyThread: TMyThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunInParallelThreadClick(Sender: TObject);
begin
// Óíè÷òîæàåì çàïóùåííûé ïîòîê
if Assigned(FMyThread) then
FreeAndNil(FMyThread);
// Ñîçäà¸ì ïîòîê â ñïÿùåì ñîñòîÿíèè
FMyThread := TMyThread.Create(True);
// Çàïîìèíàåì äëèíó ðÿäà â ïîëå MaxValue
FMyThread.MaxValue := StrToIntDef(edMaxValue.Text, 0);
// Ïðîáóæäàåì ïîòîê äëÿ âûïîëíåíèÿ âû÷èñëåíèé
FMyThread.Resume;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FMyThread.Free;
end;
{ TMyThread }
procedure TMyThread.Execute;
var
Res: Int64;
CurrVal: Integer;
begin
// Âûñòàâëÿåì ïàðàìåòðû êîìïîíåíòà ProgressBar1
Synchronize(SetProgressParams);
// Âûïîëíÿåì íåêîòîðûå âû÷èñëåíèÿ
Res := 0;
CurrVal := 0;
while CurrVal < MaxValue do
begin
if Terminated then Break;
Inc(CurrVal);
Res := Res + CurrVal;
if CurrVal mod 10000 = 0 then
begin // Îáíîâëåíèå ïðîãðåññà âûïîëíÿåòñÿ òîëüêî 1 ðàç èç 10000
FCurrValue := CurrVal;
FResult := Res;
Synchronize(SetProgressCurrValue);
end;
end;
// Îáíîâëÿåì ïðîãðåññ â êîíöå âû÷èñëåíèé
FCurrValue := CurrVal;
FResult := Res;
Synchronize(SetProgressCurrValue);
end;
procedure TMyThread.SetProgressCurrValue;
begin
Form1.ProgressBar1.Position := FCurrValue;
Form1.labResult.Caption := IntToStr(FResult);
end;
procedure TMyThread.SetProgressParams;
begin
Form1.ProgressBar1.Max := MaxValue;
Form1.ProgressBar1.Position := 0;
Form1.labResult.Caption := '0';
end;
end.

15
Ex8/Ex8Proj.dpr Normal file
View File

@ -0,0 +1,15 @@
program Ex8Proj;
uses
Forms,
Ex8Unit in 'Ex8Unit.pas' {Form1},
MTUtils in '..\CommonUtils\MTUtils.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

76
Ex8/Ex8Proj.dproj Normal file
View File

@ -0,0 +1,76 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{b679112e-97a1-4bf5-9da6-3b2b5c441fda}</ProjectGuid>
<MainSource>Ex8Proj.dpr</MainSource>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<DCC_DependencyCheckOutputName>Ex8Proj.exe</DCC_DependencyCheckOutputName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Version>7.0</Version>
<DCC_DebugInformation>False</DCC_DebugInformation>
<DCC_LocalDebugSymbols>False</DCC_LocalDebugSymbols>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<Version>7.0</Version>
<DCC_Define>DEBUG</DCC_Define>
</PropertyGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<BorlandProject xmlns=""> <Delphi.Personality> <Parameters>
<Parameters Name="UseLauncher">False</Parameters>
<Parameters Name="LoadAllSymbols">True</Parameters>
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
</Parameters>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1049</VersionInfo>
<VersionInfo Name="CodePage">1251</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
<VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"></VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
<VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
<VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
<VersionInfoKeys Name="ProductName"></VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
<Source>
<Source Name="MainSource">Ex8Proj.dpr</Source>
</Source>
</Delphi.Personality> </BorlandProject></BorlandProject>
</ProjectExtensions>
<Import Project="$(MSBuildBinPath)\Borland.Delphi.Targets" />
<ItemGroup>
<DelphiCompile Include="Ex8Proj.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="..\CommonUtils\MTUtils.pas" />
<DCCReference Include="Ex8Unit.pas">
<ModuleName>Ex7Unit</ModuleName>
<Form>Form1</Form>
</DCCReference>
<DCCReference Include="Ex8Unit.pas">
<Form>Form1</Form>
</DCCReference>
</ItemGroup>
</Project>

BIN
Ex8/Ex8Proj.res Normal file

Binary file not shown.

97
Ex8/Ex8Unit.dfm Normal file
View File

@ -0,0 +1,97 @@
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 150
ClientWidth = 452
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnDestroy = FormDestroy
DesignSize = (
452
150)
PixelsPerInch = 96
TextHeight = 16
object Label1: TLabel
Left = 8
Top = 72
Width = 64
Height = 16
Caption = #1056#1077#1079#1091#1083#1100#1090#1072#1090':'
end
object labResult: TLabel
Left = 78
Top = 72
Width = 7
Height = 16
Caption = '0'
end
object Label2: TLabel
Left = 8
Top = 96
Width = 170
Height = 16
Caption = #1058#1077#1082#1089#1090#1086#1074#1072#1103' '#1089#1090#1088#1086#1082#1072' '#1080#1079' '#1087#1086#1090#1086#1082#1072':'
end
object labThreadStateInfo: TLabel
Left = 184
Top = 96
Width = 18
Height = 16
Caption = '???'
end
object btnRunInParallelThread: TButton
Left = 8
Top = 8
Width = 217
Height = 33
Caption = #1042#1099#1095#1080#1089#1083#1080#1090#1100' '#1089#1091#1084#1084#1091' '#1088#1103#1076#1072' '#1095#1080#1089#1077#1083' '#1076#1086':'
TabOrder = 0
OnClick = btnRunInParallelThreadClick
end
object ProgressBar1: TProgressBar
Left = 8
Top = 49
Width = 436
Height = 17
Anchors = [akLeft, akTop, akRight]
TabOrder = 1
end
object edMaxValue: TEdit
Left = 232
Top = 16
Width = 89
Height = 24
TabOrder = 2
Text = '10000000'
end
object Button1: TButton
Left = 280
Top = 88
Width = 75
Height = 25
Caption = #1058#1077#1089#1090' '#1079#1072#1084#1077#1088#1086#1074
TabOrder = 3
OnClick = Button1Click
end
object Button2: TButton
Left = 280
Top = 120
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 4
OnClick = Button2Click
end
object Timer1: TTimer
Interval = 100
OnTimer = Timer1Timer
Left = 104
Top = 72
end
end

171
Ex8/Ex8Unit.pas Normal file
View File

@ -0,0 +1,171 @@
unit Ex8Unit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MTUtils, ComCtrls, ExtCtrls, SyncObjs;
type
TMyThread = class(TThread)
private
FMaxValue: Integer;
FResult: Int64;
FCurrValue: Integer;
// Èíôîðìàöèÿ î òåêóùåì ñîñòîÿíèè ïîòîêà
FThreadStateInfo: string;
function GetThreadStateInfo: string;
procedure SetThreadStateInfo(const Value: string);
public
constructor Create(MaxValue: Integer);
procedure Execute; override;
property CalcResult: Int64 read FResult;
property CurrValue: Integer read FCurrValue;
// Ñâîéñòâî äëÿ äîñòóïà ê ñòðîêå FThreadStateInfo ñ ïîìîùüþ
// ïîòîêîçàùèùåííûõ ìåòîäîâ GetThreadStateInfo è SetThreadStateInfo
property ThreadStateInfo: string read GetThreadStateInfo write SetThreadStateInfo;
end;
TForm1 = class(TForm)
btnRunInParallelThread: TButton;
ProgressBar1: TProgressBar;
Label1: TLabel;
labResult: TLabel;
edMaxValue: TEdit;
Timer1: TTimer;
Label2: TLabel;
labThreadStateInfo: TLabel;
Button1: TButton;
Button2: TButton;
procedure btnRunInParallelThreadClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
FMyThread: TMyThread;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.btnRunInParallelThreadClick(Sender: TObject);
var
MaxValue: Integer;
begin
// Óíè÷òîæàåì çàïóùåííûé ïîòîê
if Assigned(FMyThread) then
FreeAndNil(FMyThread);
MaxValue := StrToInt(edMaxValue.Text);
ProgressBar1.Max := MaxValue;
ProgressBar1.Position := 0;
labResult.Caption := '0';
labThreadStateInfo.Caption := '???';
FMyThread := TMyThread.Create(MaxValue);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
p: TPerformanceEvents;
//p1, p2: Int64;
begin
{QueryPerformanceCounter(p1);
QueryPerformanceCounter(p2);
ShowMessageFmt('p1=%d, p2=%d', [p1,p2]);}
p.StartEvent('Ýòàï 1');
//Sleep(1);
p.StopEvent();
p.StartEvent('Ýòàï 1');
Sleep(20);
p.StopEvent();
p.StartEvent('Ýòàï 2');
Sleep(30);
p.StopEvent('Ýòàï 3');
{ShowMessage(p.GetEventsAsString([eoWriteStartTime, eoWriteAllTime,
eoUseMicroSec, eoWriteFromStart, eoWriteBegTime, eoWriteEndTime]));}
ShowMessage(p.GetEventsAsString([eoUseMicroSec]));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
p: TPerformance;
begin
p.Start;
Sleep(100);
//p.Stop;
{ShowMessageFmt('%d', [p.ElapsedMilliseconds]);
ShowMessageFmt('%d', [p.ElapsedMilliseconds]);
ShowMessageFmt('%d', [p.ElapsedMilliseconds]); }
ShowMessageFmt('%s', [FormatDateTime('hh:nn:ss.zzz', p.ElapsedTime)]);
ShowMessageFmt('%s', [FormatDateTime('hh:nn:ss.zzz', p.ElapsedTime)]);
ShowMessageFmt('%s', [FormatDateTime('hh:nn:ss.zzz', p.ElapsedTime)]);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(FMyThread);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Assigned(FMyThread) then
begin
ProgressBar1.Position := FMyThread.CurrValue;
labResult.Caption := IntToStr(FMyThread.CalcResult);
labThreadStateInfo.Caption := FMyThread.ThreadStateInfo;
end;
end;
{ TMyThread }
constructor TMyThread.Create(MaxValue: Integer);
begin
FMaxValue := MaxValue;
inherited Create(False);
end;
procedure TMyThread.Execute;
begin
ThreadStateInfo := 'Start';
while FCurrValue < FMaxValue do
begin
if Terminated then Break;
Inc(FCurrValue);
FResult := FResult + FCurrValue;
ThreadStateInfo := Format('Progress: %f%%',
[FCurrValue / FMaxValue * 100]);
end;
ThreadStateInfo := 'Complete';
end;
function TMyThread.GetThreadStateInfo: string;
begin
// Çàùèùàåì ñòðîêó ñ ïîìîùüþ êðèòè÷åñêîé ñåêöèè. Åñëè å¸ óáðàòü,
// òî â ãëàâíîì ïîòîêå ïåðèîäè÷åñêè áóäåò âîçíèêàòü îøèáêà
// "Invalid pointer operation" ëèáî "Out of memory"
StringProtectSection.Enter; // Âõîäèì â ðåæèì çàùèòû
Result := FThreadStateInfo;
StringProtectSection.Leave; // Âûõîäèì èç ðåæèìà çàùèòû
end;
procedure TMyThread.SetThreadStateInfo(const Value: string);
begin
StringProtectSection.Enter; // Âõîäèì â ðåæèì çàùèòû
FThreadStateInfo := Value;
StringProtectSection.Leave; // Âûõîäèì èç ðåæèìà çàùèòû
end;
end.