Thread 동기화를 공부하며 Critical Section, Mutex, Semaphore 가 있다는 걸 알았다
그 중 Critical Section 사용법에 대해 찾아보았다
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ExtCtrls, Syncobjs;
type
TThreadArrow1 = class(TThread)
procedure Execute; override;
end;
TThreadArrow2 = class(TThread)
procedure Execute; override;
end;
type
TForm1 = class(TForm)
Panel1: TPanel;
ListBox1: TListBox;
ListBox2: TListBox;
Image1: TImage;
Image2: TImage;
Button1: TButton;
ProgressBar1: TProgressBar;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
XValue : Integer = 20;
Thread1 : TThreadArrow1;
Thread2 : TThreadArrow2;
LockValue : TCriticalSection; // uses 절에 Syncojbs 추가
implementation
{$R *.dfm}
procedure TThreadArrow1.Execute;
begin
while true do
begin
LockValue.Acquire;
// Acquire 메소드를 호출하면 Release 될 때까지 다른 Thread에서 공유자원을 사용할 수 없다
try
XValue := XValue + 1;
Form1.Image1.Left := XValue;
Form1.ListBox1.Items.Add(IntToStr(Form1.Image1.Left));
if XValue > 70 then exit;
finally
Lockvalue.Release;
end;
Sleep(100);
end;
end;
procedure TThreadArrow2.Execute;
var
i : integer;
begin
while true do
begin
LockValue.Acquire;
try
XValue := XValue + 10;
Form1.Image2.Left := XValue;
Form1.ListBox2.Items.Add(IntToStr(Form1.Image2.Left));
XValue := XValue - 10;
if XValue > 70 then exit;
finally
LockValue.Release;
end;
Sleep(100);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
LockValue := TCriticalSection.Create;
Thread1 := TThreadArrow1.Create(false);
Thread2 := TThreadArrow2.Create(false);
end;
{ Thread Create 매개변수를 false를 넘기면서 Thread를 바로 실행
true를 주는 경우 Thread가 생성되나 Suspended(멈춤) 상태로 resume(다시 실행) 메소드를 사용하여 실행해야 한다 }
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
LockValue.Free;
Thread1.Free;
Thread2.Free;
end;
end.
이 예제에서는 Thread1, Thread2인 두 개의 Thread를 생성해서 공유하는 변수를 가지고 각각 다른 숫자를 찍어보도록 한다.
만약 CriticalSection이 없는 상태에서 Thread1, Thread2가 공유하는 XValue 값을 가지고 Button1을 클릭하게 되면 listbox에 숫자가 뒤죽박죽으로 찍히게 된다.
따라서 동기화 방법 중 하나인 CriticalSection을 추가하여 각 listbox에 숫자가 연속적으로 출력되도록 했다.