Q&A

  • Thread 에서 인수를 받는 방법?
델파이 왕허접 달벌레입니다.

스레드 사용에 있어서



========================================

type

TMyThread = class(TThread)

protected

procedure Execute; override;

end;



procedure TMyThread.Execute;

var

i: Integer;

begin

for i := 1 to 10000 do

begin

FmMain.Label1.Caption:=IntToStr(i); // 라벨에다 1 부터 10000까지 찍어롸~

FmMain.Label2.Caption:=IntToStr(i); // 똑같이 하여라~



if IsExit then break; // IsExit 값이 참이면 스레드가 종료

end;

end;

========================================



위와같이 만든것은 문제없이 잘돌아갑니다.

그러나 여기서 인수를 추가하고 싶은데 어떻게 해야될지 모르겠네요

예를들면 다음같이



========================================

procedure PrintLabel(no: Integer); // no 라는 인수를 받아서

begin

for i := no to 10000 do // no 라는 인수부터 찍고 싶은데

begin

FmMain.Label1.Caption:=IntToStr(i); // 라벨에다 no 부터 10000까지 찌거라~

FmMain.Label2.Caption:=IntToStr(i);



if IsExit then break; // IsExit 값이 참이면 종료

end;

end;

========================================



저걸 스레드로 돌리려니 막막하네여



인수를 안받고 전역변수를 쓰면 해결될것 같긴한데 그렇게 하면

의미가 없고요.

스레드 게시물을 홀랑 뒤져바도 잘 이해가... ㅜ.ㅜ



스레드에서 인수를 받아서 처리하는 방법을 지도바랍니다.

3  COMMENTS
  • Profile
    kuma 2001.07.03 04:51
    간단히 api로 만드는 방식을 올려 드릴께요...

    후에 더 추가 하시면 될것도 같군요....

    일단 이벤트만 사용하고 있고요....

    만약 서로 동기화를 시키려면 동기화 방식을 추가하면 될것 같군요...



    unit Unit1;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    StdCtrls;



    type

    TForm1 = class(TForm)

    Label1: TLabel;

    Label2: TLabel;

    Button1: TButton;

    Button2: TButton;

    Button3: TButton;

    procedure Button1Click(Sender: TObject);

    procedure Button2Click(Sender: TObject);

    procedure Button3Click(Sender: TObject);

    private

    hThread: THandle; // 스레드 핸들

    hEvent: THandle; // 스레드 종료 용 이벤트 핸들

    public

    end;



    var

    Form1: TForm1;



    implementation



    {$R *.DFM}





    // 인자로 자기자신( Form1 )을 보내는 방식

    function

    WorkProc

    (

    Com: TForm1

    ): LongInt; stdcall;

    var

    iret,

    iI: integer;

    begin

    for iI := 0 to 10000 do

    begin

    iret := WaitForSingleObject( Com.hEvent, 10 );

    // 만약 종료 이벤트가 발생했을 경우

    if ( iret = WAIT_OBJECT_0 ) then

    Break

    else

    // 종료 이벤트가 발생하지 않을 경우 수를 출력

    begin

    Com.Label1.Caption := inttostr( iI );

    Com.Label2.Caption := inttostr( iI );

    end;

    end;

    result := 0;

    end;





    procedure

    TForm1.Button1Click

    (

    Sender: TObject

    );

    var

    dummy: DWORD;

    begin

    // 폼을 인자로 보내는 스레드 생성

    hThread := CreateThread( nil, 0, @WorkProc, Pointer( Self ), 0 ,dummy );

    if ( hThread = 0 ) then Exit;

    // 종료용 이벤트 생성

    hEvent := CreateEvent( nil, true, false, nil );

    if ( hEvent = 0 ) then Exit;

    button3.Enabled := false;

    end;







    procedure

    TForm1.Button2Click

    (

    Sender: TObject

    );

    begin

    // 종료 이벤트를 날림

    if ( SetEvent( hEvent ) ) then

    begin

    sleep( 10 );

    // 핸들을 종료 시킴

    CloseHandle( hThread );

    CloseHandle( hEvent );

    if ( not button1.Enabled ) then button1.Enabled := true;

    if ( not button3.Enabled ) then button3.Enabled := true;

    end;

    end;





    // 인자로 숫자를 보내는 경우 ( workProc와 마찬가지 )

    function

    WorkProc2

    (

    iI: Integer

    ): LongInt; stdcall;

    var

    iJ,

    iIdx,

    iret: integer;

    begin

    iIdx := Integer( iI );

    for iJ := iIdx to 10000 do

    begin

    iret := WaitForSingleObject( Form1.hEvent, 10 );

    if ( iret = WAIT_OBJECT_0 ) then

    Break

    else

    begin

    Form1.Label1.Caption := inttostr( iJ );

    Form1.Label2.Caption := inttostr( iJ );

    end;

    end;

    result := 0;

    end;









    procedure

    TForm1.Button3Click

    (

    Sender: TObject

    );

    var

    dummy: DWORD;

    begin

    hThread := CreateThread( nil, 0, @WorkProc2, Pointer( 100 ), 0 ,dummy );

    if ( hThread = 0 ) then Exit;

    hEvent := CreateEvent( nil, true, false, nil );

    if ( hEvent = 0 ) then Exit;

    button1.Enabled := false;

    end;



    end.









    달벌레 wrote:

    > 델파이 왕허접 달벌레입니다.

    > 스레드 사용에 있어서

    >

    > ========================================

    > type

    > TMyThread = class(TThread)

    > protected

    > procedure Execute; override;

    > end;

    >

    > procedure TMyThread.Execute;

    > var

    > i: Integer;

    > begin

    > for i := 1 to 10000 do

    > begin

    > FmMain.Label1.Caption:=IntToStr(i); // 라벨에다 1 부터 10000까지 찍어롸~

    > FmMain.Label2.Caption:=IntToStr(i); // 똑같이 하여라~

    >

    > if IsExit then break; // IsExit 값이 참이면 스레드가 종료

    > end;

    > end;

    > ========================================

    >

    > 위와같이 만든것은 문제없이 잘돌아갑니다.

    > 그러나 여기서 인수를 추가하고 싶은데 어떻게 해야될지 모르겠네요

    > 예를들면 다음같이

    >

    > ========================================

    > procedure PrintLabel(no: Integer); // no 라는 인수를 받아서

    > begin

    > for i := no to 10000 do // no 라는 인수부터 찍고 싶은데

    > begin

    > FmMain.Label1.Caption:=IntToStr(i); // 라벨에다 no 부터 10000까지 찌거라~

    > FmMain.Label2.Caption:=IntToStr(i);

    >

    > if IsExit then break; // IsExit 값이 참이면 종료

    > end;

    > end;

    > ========================================

    >

    > 저걸 스레드로 돌리려니 막막하네여

    >

    > 인수를 안받고 전역변수를 쓰면 해결될것 같긴한데 그렇게 하면

    > 의미가 없고요.

    > 스레드 게시물을 홀랑 뒤져바도 잘 이해가... ㅜ.ㅜ

    >

    > 스레드에서 인수를 받아서 처리하는 방법을 지도바랍니다.

  • Profile
    나그네 2001.07.02 17:43
    스레드내에 변수를 선언하고 스레드를 전달하면 될 것 같네요

    동기화문제가 있을 것 같은데 생략하겠습니다.



    > ========================================

    > type

    > TMyThread = class(TThread)

    > protected

    > procedure Execute; override;

    public

    iCount: integer;

    > end;



    > ========================================



  • Profile
    달벌레 2001.07.03 12:30
    덕분에 먼가 실마리가 풀려가는거 같습니다.

    스레드 어렵긴 어렵군요 ㅜ.ㅜ



    완성의 그날까지 아자~