-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathSimpleThreadpoolDemo.lpr
More file actions
106 lines (90 loc) · 3.21 KB
/
Copy pathSimpleThreadpoolDemo.lpr
File metadata and controls
106 lines (90 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
program SimpleThreadpoolDemo;
{$mode objfpc}{$H+}{$J-} // Standard FPC mode directives
uses
{$IFDEF UNIX}
cthreads, // MUST be first: enables threading support on Unix/Linux
{$ENDIF}
Classes, // For TThread and other basic classes
SysUtils, // For string handling and formatting
ThreadPool.Simple, // Our thread pool implementation
syncobjs; // For TCriticalSection and synchronization
type
{ TDataProcessor - Example class showing thread-safe processing }
TDataProcessor = class
private
FCS: TCriticalSection; // Protects access to shared resources
FProcessedCount: Integer; // Counter of processed items (shared resource)
public
constructor Create;
destructor Destroy; override;
procedure ProcessItem(index: Integer);
property ProcessedCount: Integer read FProcessedCount;
end;
{ Simple procedure to demonstrate basic thread execution }
procedure SimpleProcedure;
begin
WriteLn('Hello from thread #', ThreadID); // ThreadID is provided by the system
end;
{ Procedure with parameter to demonstrate indexed operations }
procedure ProcessWithIndex(AIndex: Integer);
begin
WriteLn('Processing item: ', AIndex);
end;
{ TDataProcessor implementation }
constructor TDataProcessor.Create;
begin
inherited Create;
FCS := TCriticalSection.Create; // Create synchronization object
FProcessedCount := 0; // Initialize counter
end;
destructor TDataProcessor.Destroy;
begin
FCS.Free; // Clean up synchronization object
inherited; // Always call inherited destructor last
end;
procedure TDataProcessor.ProcessItem(index: Integer);
begin
Sleep(100); // Simulate some work (not needed in real code)
// Thread-safe increment of counter
FCS.Enter; // Lock the critical section
try
Inc(FProcessedCount);
WriteLn(Format('Processed item %d (Total: %d)', [index, FProcessedCount]));
finally
FCS.Leave; // Always unlock in finally block
end;
end;
var
Processor: TDataProcessor;
CustomPool: TSimpleThreadPool;
i: Integer;
begin
WriteLn('ThreadPool Basic Usage Demo');
WriteLn('-------------------------');
{ Example 1: Using the global thread pool (simplest approach) }
WriteLn('1. Using GlobalThreadPool:');
GlobalThreadPool.Queue(@SimpleProcedure); // Queue a simple procedure
GlobalThreadPool.WaitForAll; // Wait for completion
{ Example 2: Using global pool with indexed operations }
WriteLn('2. Using GlobalThreadPool with index:');
for i := 1 to 3 do
GlobalThreadPool.Queue(@ProcessWithIndex, i); // Queue with parameter
GlobalThreadPool.WaitForAll;
{ Example 3: Using custom thread pool for more control }
WriteLn('3. Using TSimpleThreadPool:');
CustomPool := TSimpleThreadPool.Create(4); // Create pool with 4 threads
Processor := TDataProcessor.Create;
try
// Queue multiple items for parallel processing
for i := 1 to 5 do
CustomPool.Queue(@Processor.ProcessItem, i);
CustomPool.WaitForAll;
WriteLn(Format('Total items processed: %d', [Processor.ProcessedCount]));
finally
// Clean up (always in reverse order of creation)
Processor.Free;
CustomPool.Free;
end;
WriteLn('Press Enter to exit...');
ReadLn;
end.