상세 컨텐츠

본문 제목

ThreadPool

RyuLib/RyuLib for Delphi

by ryujt 2012. 1. 18. 06:05

본문

쓰레드 클래스를 생성하지 않고 함수 호출만으로 쓰레드를 사용하기 위한 유닛입니다.  "RyuLib for Delphi" 소스는 아래의 링크에서 받으시기 바랍니다.

http://ryulib.tistory.com/notice/11 


사용법은 [소스 1]과 같습니다.

[소스 1]
function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
begin
  Result := 0;

  // TOO : 
end;

procedure TfmMain.btCalcClick(Sender: TObject);
begin
  QueueWorkItem(InternalThreadFunction, nil);
end;
10: 새로운 함수를 쓰레드 풀에 넣어서 실행 시킬 수 있을 때 함수가 실행됩니다.  쓰레드 생성 등에 대한 오버 헤드가 없습니다.

1-6: 함수의 형태는 1-6: 라인과 같아야 합니다.

1: lpThreadParameter 인자는 쓰레드와 호출 객체가 서로 공유 할 데이터나 객체를 전달 받기 위한 것입니다.  필요없으면 사용하지 않아도 됩니다.

ThreadPool 유닛에는 [소스 2]와 같은 형태의 함수가 제공됩니다.  각각 필요한 작업에 따라 선택하시면 됩니다.

[소스 2]
function QueueWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;
function QueueIOWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;
function QueueUIWorkItem(Func:TThreadStartRoutine; Context:Pointer):boolean;


[소스 3]은 1부터 n까지 더하는 프로그램을 멀티 쓰레드로 작성해 본 것 입니다.  속도를 줄이기 위해서 중간에 Sleep(1)로 쉬도록 했습니다.  [그림 1]은 실행 결과 화면이며, 1000 --> 100 --> 10 순으로 계산을 했지만, 멀티 쓰레드이다 보니 먼저 계산 된 것부터 표시되고 있습니다.  가장 처음 입력한 수는 좀 큰 수였는데, 한 참 동안 계산이 안끝나서 중간에 캡쳐된 것을 올립니다.

[그림 1] 실행 결과


[소스 3]
unit _fmMain;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Samples.Spin;

type
  TfmMain = class(TForm)
    btCalc: TButton;
    ListBox1: TListBox;
    SpinEdit1: TSpinEdit;
    procedure btCalcClick(Sender: TObject);
  private
    procedure do_WM_User(var Msg:TMessage); message WM_User;
  public
  end;

var
  fmMain: TfmMain;

implementation

uses
  ThreadPool;

{$R *.dfm}

type
  TContext = class
    n : integer;
    Handle : THandle;
  end;

function InternalThreadFunction(lpThreadParameter: Pointer): Integer; stdcall;
var
  Loop, Sum : integer;
  Context : TContext absolute lpThreadParameter;
begin
  Result := 0;

  Sum := 0;
  for Loop := 1 to Context.n do begin
    Sum := Sum + Loop;
    Sleep(1);
  end;

  PostMessage(Context.Handle, WM_User, Sum, Context.n);
end;

procedure TfmMain.btCalcClick(Sender: TObject);
var
  Context : TContext;
begin
  Context := TContext.Create;
  try
    Context.n := SpinEdit1.Value;
    Context.Handle := Self.Handle;
    QueueWorkItem(InternalThreadFunction, Context);
  finally
    Context.Free;
  end;
end;

procedure TfmMain.do_WM_User(var Msg: TMessage);
begin
  ListBox1.Items.Add(Format('Sum = %d, n = %d', [Msg.WParam, Msg.LParam]));
end;

end.
 

'RyuLib > RyuLib for Delphi' 카테고리의 다른 글

LazyRelease - 메모리 해제를 뒤로 미루기  (0) 2012.10.21
JsonFormatter unit 추가  (0) 2012.08.02
A Simple thread class that can change stack size for it  (0) 2012.07.01
DynamicQueue unit  (0) 2012.06.28
ObserverList  (0) 2010.12.13

관련글 더보기