Sign in Join
Wiki copytemporary

MultithreadingAndCriticalsections: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: MultithreadingAndCriticalsections

OldNewLine
1+## Code Snippet demonstrating Thread programming
2+
3+``` pascal
4+{$mode objfpc}{$H+}
5+program Project1;
6+
7+uses
8+ {$ifdef unix}cthreads,
9+ {$endif}Classes,
10+ SysUtils;
11+
12+var
13+ CriticalSection: TRTLCriticalSection;
14+ Counter: integer;
15+ UseCriticalSection: boolean;
16+
17+ function Supposedly: string;
18+ begin
19+ if UseCriticalSection then
20+ Result:=''
21+ else Result:='supposedly ';
22+ end;
23+
24+type
25+ { TMyThread }
26+
27+ TMyThread = class(TThread)
28+ private
29+ FAFinished: boolean;
30+ FID: integer;
31+ public
32+ constructor Create(CreateSuspended: Boolean; ID: integer; const StackSize: SizeUInt=DefaultStackSize);
33+ procedure Execute; override;
34+ property AFinished: boolean read FAFinished write FAFinished;
35+ end;
36+
37+ constructor TMyThread.Create(CreateSuspended: Boolean; ID: integer; const StackSize: SizeUInt);
38+ begin
39+ inherited Create(CreateSuspended, StackSize);
40+ FID:=ID;
41+ end;
42+
43+ procedure TMyThread.Execute;
44+ var
45+ j: integer;
46+ begin
47+ FAFinished := False;
48+ if UseCriticalSection then
49+ EnterCriticalSection(CriticalSection);
50+ try
51+ for j := 1 to 1000000 do
52+ Inc(Counter);
53+ WriteLn(Format('Thread %d has %sfinished making 1000000 increments to Counter',[FID, Supposedly]));
54+ finally
55+ if UseCriticalSection then
56+ LeaveCriticalSection(CriticalSection);
57+ end;
58+ FAFinished := True;
59+ end;
60+
61+ function HasCriticalSection: string;
62+ begin
63+ if UseCriticalSection then
64+ Result:=''
65+ else Result:='NOT ';
66+ end;
67+
68+ procedure ExerciseThreads(aUseCriticalSection: boolean);
69+ var
70+ Threads: array[1..20] of TMyThread;
71+ AllFinished: boolean;
72+ i: integer;
73+ begin
74+ Counter := 0;
75+ UseCriticalSection:=aUseCriticalSection;
76+ WriteLn(Format('A critical section is %sbeing used; Counter starts at %d',[HasCriticalSection, Counter]));
77+ // start 20 threads
78+ for i := Low(Threads) to High(Threads) do
79+ Threads[i] := TMyThread.Create(False, i);
80+ // wait till all threads finished
81+ repeat
82+ AllFinished := True;
83+ for i := Low(Threads) to High(Threads) do
84+ if not Threads[i].AFinished then
85+ AllFinished := False;
86+ until AllFinished;
87+ // free the threads
88+ for i := Low(Threads) to High(Threads) do
89+ Threads[i].Free;
90+ WriteLn('Final value of Counter=' + IntToStr(Counter));
91+ WriteLn;
92+ end;
93+
94+var
95+ b: boolean;
96+begin
97+ // create the CriticalSection
98+ InitCriticalSection(CriticalSection);
99+
100+ for b in Boolean do
101+ ExerciseThreads(b);
102+
103+ // free the CriticalSection
104+ DoneCriticalSection(CriticalSection);
105+
106+ {$IfDef WINDOWS}
107+ Write(' Press [Enter] to finish');
108+ ReadLn;
109+ {$EndIf}
110+end.
111+```
112+
113+---
114+*From the Free Pascal wiki, page "MultithreadingAndCriticalsections", as it stood on 2021-05-06 after a change by Arent, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history