スレッドが終了したかを知るには?

解決


nish  2005-07-01 02:39:12  No: 16104

スレッドが終了したかを知るのに何かありますか?

現在、スレッドに状態フラグを渡して、
スレッドのコントストラクトでTrueにし、
スレッドが終了する時にFalseにしています。
何か簡単に知る術はありますか?

Delphi6 Enterprise使用。


nish  2005-07-01 03:10:52  No: 16105

終了時にwaitを使ってみたのですが
アクセスエラーがでてしまいました。

  if Thread1 <> nil then
  begin
      Thread1.Terminate;
      Thread1.wait;
  end;


nish  2005-07-01 03:18:57  No: 16106

度々すみません。
コード間違えました。
×Thread1.wait;
○Thread1.WaitFor;

スレッドが終了した時にThread1にnilが入るような
処理?イベント?はないんでしょうか?


メラトニン  2005-07-04 02:53:24  No: 16107

OnTerminateイベントでしょう。
以下サンプルです
ちなみにTMyThread内に途中終了処理が無いので途中終了しません。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMeThread = class(TThread)
  private
    { Private 宣言 }
  protected
    procedure Execute; override;
  end;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
    MeThread1 :TThread;
    procedure MeThread1Terminate(Sender: TObject);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

uses Math;

{$R *.dfm}

{ TMeThread }

procedure TMeThread.Execute;
var i:Integer;
begin
  inherited;
  for i:=0 to 100 do
    Sleep(10);

  beep;
end;

////////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
begin
  If MeThread1=nil then
  begin
    caption:='作成しました';
    MeThread1:=TMeThread.Create(True);
    MeThread1.FreeOnTerminate:=True;
    MeThread1.OnTerminate:=MeThread1Terminate;
    MeThread1.Resume;
  end else begin
    caption:='終了要求出しました';
    MeThread1.Terminate;
  end;

end;

procedure TForm1.MeThread1Terminate(Sender: TObject);
begin
  MeThread1:=nil;
  caption:='破棄しました';
end;

end.


nish  2005-07-04 21:26:04  No: 16108

OnTerminateなんてあるんですね!?
見落としてました(^^;

ちなみにマルチスレッドの時は
どう判定してnilを入れればいんでしょうか?


メラトニン  2005-07-04 21:57:40  No: 16109

マルチスレッドじゃなくって複数のTThreadを作成した時ですよね?

MeThread1.OnTerminate:=MeThread1Terminate;
MeThread2.OnTerminate:=MeThread1Terminate;
MeThread3.OnTerminate:=MeThread1Terminate;

としたら
procedure TForm1.MeThread1Terminate(Sender: TObject);
begin
  TMeThread(Sender):=nil;
end;

(Sender: TObject)の中身が送り主のTMeThreadです。


にしの  2005-07-04 22:52:13  No: 16110

> (Sender: TObject)の中身が送り主のTMeThreadです。
Senderは、送り主のTMeThreadオブジェクトですが、入れ物は違うかもしれませんよ。
引数はvarではありませんし。
TListなどで管理して、Terminateしたらリストから消してやるほうがよいかと思います。


nish  2005-07-05 00:38:30  No: 16111

メラトニンさん、にしのさんありがとうございます。
とても勉強になります。

あと初歩的な質問なんですが、、、
> マルチスレッドじゃなくって複数のTThreadを作成した時ですよね?
って、マルチスレッドと複数のTThread作成って
どう違うのすか?
同じものだと思っていましたので。。。


anone  2005-07-05 00:43:35  No: 16112

暗黙のうちに作られるメインスレッドがあるから。TThread の派生クラスのインスタンスを
ひとつ作った時点ですでにマルチスレッドと言える。


nish  2005-07-05 01:08:01  No: 16113

あ〜なるほど!
ありがとうございました。


メラトニン  2005-07-05 03:17:27  No: 16114

にしのさん
>>TMeThread(Sender):=nil;
確かにこれは問題あるかもしれません、
[[解決]]付いたって事はnishさん分かってるのかな?


anone  2005-07-06 22:28:54  No: 16115

> 確かにこれは問題あるかもしれません

絶対問題があるでしょう。特定の変数に nil を代入したいときに
そのインスタンスをキャストして代入してもまったく無意味です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加