[210507] CriticalSection(Thread Synchronization)

Donghee Lee·2021년 5월 7일
0

Delphi

목록 보기
9/13

Thread Critical Section

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에 숫자가 연속적으로 출력되도록 했다.

profile
Better than Yesterday

0개의 댓글