多线程问题,请大家讨论,有部分代码(50分)

Q

qddmh

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了一个多线程程序如下:
主要是创建4个线程, 通过timer组件监控,当一个线程执行完毕后,重新创建。
有以下几个问题清讨论:
1。我的程序保持四个线程的方法是通过Timer组件监控。
2。释放线程后又重新创建。
我总感觉这种方法不好, 影响效率。
所以我想问
1。是否有其他方法来监控那个线程是否执行完?(例如消息控制?怎样做?)
2。能不能当一个线程执行完一个任务后,将它悬挂, 给它另一个任务后,在启动它,
如能应怎样做?这样就不用频繁的创建线成了。
3。我想问一下FlashGet的实现原理,也就是多线程多任务的解决方案。
欢迎大家讨论
美分了,
unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, myThread1, ExtCtrls;
const
WM_ThreadDoneMsg = WM_User + 8;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Timer1: TTimer;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
StartThread: Boolean;
//避免开始创建窗体时Timer组件执行
AllDo: Boolean;
//停止线程标志
procedure ThreadDone(var AMessage : TMessage);
message WM_ThreadDoneMsg;
// Message to be sent back from thread when itsdo
ne
public
{ Public declarations }
end;

var
Form1: TForm1;
myThread: Array[0..3] of TMyThread;
ThreadActive: Array[0..3] of Boolean;
TaskNum: Integer;
implementation


{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
begin
for i := 0 to 3do
begin
if ((myThread = nil) or (ThreadActive = False)) then
begin
myThread := TmyThread.Create;
ThreadActive := True;
end
else
Showmessage('Thread Still Executing');
end;
StartThread := True;
AllDo := False;
Timer1.Enabled := True;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
for i := 0 to 4do
begin
ThreadActive := False;
myThread := nil;
end;
StartThread := False;
AllDo := False;
end;

procedure TForm1.ThreadDone(var AMessage: TMessage);
var
i: integer;
begin
for i := 0 to 3do
begin
if ((MyThread <> nil) and (MyThread.ThreadID = cardinal(AMessage.WParam))) then
ThreadActive := False;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
i: integer;
begin
for i := 0 to 3do
begin
if (MyThread <> nil) and (ThreadActive = True) then
begin
MyThread.Terminate;
MyThread.WaitFor;
end;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin
if AllDo = True then
begin
timer1.Enabled := False;
Exit;
end;
for i := 0 to 3do
begin

if (((myThread = nil) and (StartThread = True)) or ((ThreadActive = False) and (StartThread = True))) then
begin
myThread := TmyThread.Create;
ThreadActive := True;
end;
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
AllDo := True;
end;

end.

/////////////////////////////////////////////////////////////////////////////////
unit myThread1;
interface
uses
windows, Classes, comctrls, ShellAPI, Dialogs;
type
TMyThread = class(TThread)
private
procedure Showm;
protected
procedure Execute;
override;
public
constructor Create;
Destructor Destroy;
override;
end;
implementation
uses main;
{ MyThread }
constructor TMyThread.Create;
begin
inherited Create(True);
FreeOnTerminate := True;
Resume;
end;

destructor TMyThread.Destroy;
begin
PostMessage(form1.Handle,wm_ThreadDoneMsg,self.ThreadID,0);
inherited Destroy;
end;

procedure TMyThread.Execute;
begin
inherited;
Synchronize(Showm);
end;

procedure TMyThread.Showm;
begin
Form1.Memo1.Lines.Add('sss');
end;

end.
 
代码比较厂, 但很简单
大伙都发表一下自己的见解把
 
为什么没有响应的呢?
 
埃, 让我的热情消失一尽
 
你的热情消失得太快了吧
第一个问题
使用线程的OnTerminate句柄可以知道线程什么时候执行完
procedure TForm1.OnThreadTerm(Sender: TObject)
begin
//这里的Sender就是对应的线程实例
end;

with TMyThread.Createdo
begin
OnTerminate := Self.OnThreadTerm;
end;

第二个问题,改写以下的方法
procedure TMyThread.Execute;
begin
while not Terminateddo
begin
Synchronize(Showm);
Suspend;
end;
end
要控制线程运行只要调用它的Resume方法即运行一次,要结束线程,只需要调用它的
Terminate方法再Resume即可。
至于FlashGet一类的下载工具,我觉得只要掌握了这些方法就可以触类旁通了
 
再onterminate中发送消息通知main线程.
 
第二个问题可以看看scktcomp单元的源代码,使用TServerSocket时,如果选择阻塞方式会
建立一个线程缓冲池,当一个新的客户连上来,就会从线程缓冲池里取一个空闲线程服务
该客户,客户断开后又把该线程放回到缓冲池。看TServerClientThread类和TServerWinSock类
 
谢谢各位, 继续讨论
我先将这些总结总结
 
接受答案了.
 

Similar threads

I
回复
0
查看
466
import
I
I
回复
0
查看
509
import
I
I
回复
0
查看
553
import
I
I
回复
0
查看
674
import
I
顶部