-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathProdConSquareNumbers.lpr
More file actions
112 lines (94 loc) · 2.58 KB
/
Copy pathProdConSquareNumbers.lpr
File metadata and controls
112 lines (94 loc) · 2.58 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
107
108
109
110
111
112
program ProdConSquareNumbers;
{$mode objfpc}{$H+}{$J-}
uses
{$IFDEF UNIX}
cthreads, // MUST be first: enables threading support on Unix/Linux
{$ENDIF}
Classes, SysUtils, ThreadPool.ProducerConsumer, SyncObjs;
const
ARRAY_SIZE = 2000;
type
TNumberArray = array of Integer;
var
Numbers: TNumberArray; // Input numbers
Squares: TNumberArray; // Results
Lock: TCriticalSection;
ProcessedCount: Integer;
// Process a number at given index
procedure SquareNumber(Index: Integer);
var
Square: Integer;
LocalCount: Integer;
begin
// Calculate square
Square := Numbers[Index] * Numbers[Index];
// Store result thread-safely
Lock.Enter;
try
Squares[Index] := Square;
Inc(ProcessedCount);
LocalCount := ProcessedCount; // Get current count safely
finally
Lock.Leave;
end;
// Show progress every 1000 items
if LocalCount mod 1000 = 0 then
WriteLn(Format('Progress: %d/%d', [LocalCount, ARRAY_SIZE]));
end;
var
Pool: TProducerConsumerThreadPool;
I: Integer;
// Main program
begin
ProcessedCount := 0; // Initialize counter
// Initialize arrays
SetLength(Numbers, ARRAY_SIZE);
SetLength(Squares, ARRAY_SIZE);
Lock := TCriticalSection.Create;
try
// Fill input array with numbers 1 to 200
for I := 0 to ARRAY_SIZE - 1 do
Numbers[I] := I + 1;
// Create thread pool
Pool := TProducerConsumerThreadPool.Create;
try
WriteLn('Processing squares of numbers 1 to ', ARRAY_SIZE);
// Queue all numbers for processing
for I := 0 to ARRAY_SIZE - 1 do
begin
try
Pool.Queue(@SquareNumber, I);
except
on E: Exception do
begin
if E.Message.Contains('Queue is full') then
begin
// In case the queue is full, wait, then retry again
WriteLn('Queue full, waiting...');
Pool.WaitForAll; // Wait for queue to clear
Pool.Queue(@SquareNumber, I); // Try again
end
else
raise;
end;
end;
end;
// Wait for all calculations to complete
Pool.WaitForAll;
// Show some results
WriteLn('Some results:');
for I := 0 to 9 do // Show first 10 numbers
WriteLn(Format('%d² = %d', [Numbers[I], Squares[I]]));
WriteLn('...');
for I := ARRAY_SIZE - 10 to ARRAY_SIZE - 1 do // Show last 10 numbers
WriteLn(Format('%d² = %d', [Numbers[I], Squares[I]]));
finally
Pool.Free;
end;
finally
Lock.Free;
end;
// Pause console
WriteLn('Press Enter to exit...');
ReadLn;
end.