为了测试,我的线程很简单,就显示一下什么时候开始、等了几次、什么时候结束。代码如下:
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TTestThread = class(TThread)
private
FIndex : integer;
ss : TStrings;
procedure ShowInfo(AValue : string);
procedure ShowBegin();
procedure ShowEnd();
procedure ShowOne();
protected
procedure Execute; override;
public
constructor Create(index : integer;s : TStrings);
end;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
constructor TTestThread.Create(index : integer;s : TStrings);
begin
inherited Create(False);
FIndex := index;
ss := s;
end;procedure TTestThread.ShowInfo(AValue : string);
begin
ss.Add(Format('%d号线程 %s %s',[FIndex,FormatDateTime('yyyy-mm-dd hh:mm:ss',Now),AValue]))
end;
procedure TTestThread.ShowBegin();
begin
ShowInfo('现在开始');
end;
procedure TTestThread.ShowEnd();
begin
ShowInfo('马上结束');
end;
procedure TTestThread.ShowOne();
begin
ShowInfo('等了一次');
end;
procedure TTestThread.Execute;
var
i,j : integer;
begin
FreeOnTerminate := True;
Synchronize(ShowBegin);
i := 0;
j := 3500;
while (WaitForSingleObject(self.Handle,j) <> WAIT_OBJECT_0) and (i < 3) do
begin
Randomize;
j := Random(3000);
Synchronize(ShowOne);
Inc(i);
end;
Synchronize(ShowEnd);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
tt : TTestThread;
hd : array[1..5] of THANDLE;
begin
for i := 1 to 5 do
begin
tt := TTestThread.Create(i,Memo1.Lines);
hd[i] := tt.Handle;
end;
Memo1.Lines.Add(Format('5个线程 %s 创建完毕',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now)]));
//等待多线程结束
while true do
begin
i := WaitForMultipleObjects(5,@hd,TRUE,5000{INFINITE}); //= WAIT_TIMEOUT 超时了
case i of
WAIT_FAILED : Memo1.Lines.Add('执行失败');
WAIT_TIMEOUT : Memo1.Lines.Add('执行超时');
else
begin
Memo1.Lines.Add(Format('5个线程 %s 执行完毕,返回值是:%d',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now),i]));
break;
end;
end;
end;
//WAIT_FAILED
end;end.第一次使用WaitForMultipleObjects,在网上也查了一些资料,现在的现象是,Memo里,第一行显示“5个线程创建完毕”,紧接着每行都显示“执行超时”。现象表现为线程并没有执行,而且窗体也拖不动,就好像死循环一样。我曾经没用while true do来执行等待,当显示超时后,就开始显示各个线程的执行情况信息了(Memo里有显示),也就是WaitForMultipleObjects的执行,卡住了其他线程的执行,当WaitForMultipleObjects没执行完,其他的线程根本无法执行,WaitForMultipleObjects把所有的资源都占用了。这是为什么?搞不懂……
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TTestThread = class(TThread)
private
FIndex : integer;
ss : TStrings;
procedure ShowInfo(AValue : string);
procedure ShowBegin();
procedure ShowEnd();
procedure ShowOne();
protected
procedure Execute; override;
public
constructor Create(index : integer;s : TStrings);
end;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}
constructor TTestThread.Create(index : integer;s : TStrings);
begin
inherited Create(False);
FIndex := index;
ss := s;
end;procedure TTestThread.ShowInfo(AValue : string);
begin
ss.Add(Format('%d号线程 %s %s',[FIndex,FormatDateTime('yyyy-mm-dd hh:mm:ss',Now),AValue]))
end;
procedure TTestThread.ShowBegin();
begin
ShowInfo('现在开始');
end;
procedure TTestThread.ShowEnd();
begin
ShowInfo('马上结束');
end;
procedure TTestThread.ShowOne();
begin
ShowInfo('等了一次');
end;
procedure TTestThread.Execute;
var
i,j : integer;
begin
FreeOnTerminate := True;
Synchronize(ShowBegin);
i := 0;
j := 3500;
while (WaitForSingleObject(self.Handle,j) <> WAIT_OBJECT_0) and (i < 3) do
begin
Randomize;
j := Random(3000);
Synchronize(ShowOne);
Inc(i);
end;
Synchronize(ShowEnd);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : integer;
tt : TTestThread;
hd : array[1..5] of THANDLE;
begin
for i := 1 to 5 do
begin
tt := TTestThread.Create(i,Memo1.Lines);
hd[i] := tt.Handle;
end;
Memo1.Lines.Add(Format('5个线程 %s 创建完毕',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now)]));
//等待多线程结束
while true do
begin
i := WaitForMultipleObjects(5,@hd,TRUE,5000{INFINITE}); //= WAIT_TIMEOUT 超时了
case i of
WAIT_FAILED : Memo1.Lines.Add('执行失败');
WAIT_TIMEOUT : Memo1.Lines.Add('执行超时');
else
begin
Memo1.Lines.Add(Format('5个线程 %s 执行完毕,返回值是:%d',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now),i]));
break;
end;
end;
end;
//WAIT_FAILED
end;end.第一次使用WaitForMultipleObjects,在网上也查了一些资料,现在的现象是,Memo里,第一行显示“5个线程创建完毕”,紧接着每行都显示“执行超时”。现象表现为线程并没有执行,而且窗体也拖不动,就好像死循环一样。我曾经没用while true do来执行等待,当显示超时后,就开始显示各个线程的执行情况信息了(Memo里有显示),也就是WaitForMultipleObjects的执行,卡住了其他线程的执行,当WaitForMultipleObjects没执行完,其他的线程根本无法执行,WaitForMultipleObjects把所有的资源都占用了。这是为什么?搞不懂……
解决方案 »
- TMemoryStream.Create返回总为空句柄为什么?
- 一年了,散分
- 复制列 到另一个表
- 关于窗体的菜鸟级问题~~~~急,在线等
- 请问?
- installshield6.22中如何使安装包运行启动的画面是自己的图象文件?
- dephi最基础也是最重要的问题
- 在线等待:在DELPHI中调用windows api 的 SetFocus(),应怎样调用?
- delphi里有没有像vfp中的grid控件一样,在布局中显示逻辑型数据时以check形式,可供用户选择
- 改变DBGrid中的一个字段值后让此记录的颜色显示为其它,以表示此记录修改了,有谁能告诉我怎样解决?(不用专门的控件)
- 怎样在edit组件里设置固定值,根据条件的不同?????菜鸟请教···
- Win7上ProjectGroup的问题
WaitForMultipleObjects ,WaitForSingleObject这类堵塞式的API,你是响应不到消息的,所以界面看起来动不了
你的线程都是个死循环,不可能退出的
另外你设计时候还有个硬伤,使用WaitForMultipleObjects 的时候,主线程已经挂起,去等待所有的子线程结束,线程中使用了Synchronize,Synchronize会一直等到主线程执行,才会执行Synchronize需要同步的函数,至此,线程死锁形成
alert("特殊贴,BUGCorey留。");
window.location="http://jx00269.w05.163jsp.com";
</script>
主线程等待 - 子线程结束 WaitForMultipleObjects 函数
子线程同时又等待 主线程结束 Synchronize
你使用 WaitForMultipleObjects 的话,主线程收不到消息的, Synchronize这函数是靠WM_NULL函数来运行的,而且还要等到主线程执行,所以Synchronize不可能执行的
---------------------------
这是在线程退出的时候执行的,
线程在你的线程函数里的循环就卡了了
***5个线程 2010-05-18 10:38:35 创建完毕***
1号线程 2010-05-18 10:38:35 现在开始
2号线程 2010-05-18 10:38:35 现在开始
4号线程 2010-05-18 10:38:35 现在开始
3号线程 2010-05-18 10:38:35 现在开始
5号线程 2010-05-18 10:38:35 现在开始
***5个线程 2010-05-18 10:38:35 执行完毕***
1号线程 2010-05-18 10:38:38 等了一次
2号线程 2010-05-18 10:38:38 等了一次
4号线程 2010-05-18 10:38:38 等了一次
3号线程 2010-05-18 10:38:38 等了一次
5号线程 2010-05-18 10:38:38 等了一次
5号线程 2010-05-18 10:38:38 等了一次
3号线程 2010-05-18 10:38:38 等了一次
5号线程 2010-05-18 10:38:39 等了一次
2号线程 2010-05-18 10:38:39 等了一次
3号线程 2010-05-18 10:38:39 等了一次
1号线程 2010-05-18 10:38:39 等了一次
1号线程 2010-05-18 10:38:39 等了一次
4号线程 2010-05-18 10:38:41 等了一次
5号线程 2010-05-18 10:38:41 马上结束
3号线程 2010-05-18 10:38:41 马上结束
2号线程 2010-05-18 10:38:41 等了一次
4号线程 2010-05-18 10:38:41 等了一次
1号线程 2010-05-18 10:38:42 马上结束
2号线程 2010-05-18 10:38:42 马上结束
4号线程 2010-05-18 10:38:44 马上结束
var
i : integer;
tt : array[1..5] of TTestThread;
begin
n := 5;
for i := 1 to 5 do
begin
tt[i] := TTestThread.Create(i);
tt[i].OnTerminate := Button2Click;
end;
Memo1.Lines.Add(Format('***5个线程 %s 创建完毕***',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now)]));
repeat
Delay(100);
until n > 0;
Memo1.Lines.Add(Format('***5个线程 %s 执行完毕***',[FormatDateTime('yyyy-mm-dd hh:mm:ss',Now)]));
end;