delphi多线程编程中利用事件机制同步的初步实现

来源:互联网 发布:免费视频剪辑软件app 编辑:程序博客网 时间:2024/06/05 05:44

使用delphi开发应用程序多年了,多线程开发也应用较多,近来想想, 多线程同步这一关键问题,感觉自己使用的方法较为简单:临界区,互斥量;如果是多个线程之间要在高速工作环境下进行同步,又如何更好地实现呢?于是上网找了线程同步方法,呵~~,方法很多,其中就有使用事件机制实现线程同步的;
自己平时用SPCOMM较多,研究其源码也较多,因此想通过事件来实现一下线程间的同步。想到就做到。动手吧!
Delphi7+winxp+sp2;呵~~,先定义一个线程类吧。 
type 
TNew_thread=class(TThread) //自定义线程类    
private       
FCloseEvent:THandle; //线程退出事件       
FExecuteEvent:THandle; //线程操作事件      
FMemo:TMemo;       
FTimer:TTimer; //定时触发事件用的定时器,后来扩展了一下,仅试验用;    
protected       
procedure Execute;Override;       
procedure dosth;       
procedure DoExitThrd;    
public       
procedure Start;       
procedure stopthread;       
constructor create(aMemo:Tmemo);       
procedure DoTimer(Sender:TObject);  
end;   
参考了SPCOMM源码,线程创建时,便创建了两个事件,且这两个事件都是要求手动设置信号状态,同时初始信号状态是假。  
constructor TNew_thread.create(aMemo: Tmemo);  
begin  
inherited create(true);  
FreeOnTerminate:=true;  
FCloseEvent:=CreateEvent(nil,False,False,Nil);
//创建两个事件模件,这两个事件都要求手动重置状态 
FExecuteEvent:=CreateEvent(nil,False,False,nil);  
Fmemo:=amemo;  
FTimer:=TTimer.Create(nil);  
FTimer.Interval:=1000;  
FTimer.OnTimer:=self.DoTimer;  
FTimer.Enabled:=true;  
resume;  
end;  
线程关键代码,Execute方法和重载;  
procedure TNew_thread.Execute;  
var   
EventHandleArr:Array [0..1] of THandle;    
Signaled:cardinal; 
begin    
EventHandleArr[0]:=FExecuteEvent;    
EventHandleArr[1]:=FCloseEvent;    
while not Terminated do    
begin       
signaled:=WaitForMultipleObjects(2,@EventHandleArr,False,INFINITE);       
case signaled of         
WAIT_OBJECT_0://线程执行         
begin           
self.Synchronize(dosth);         
end;         
WAIT_OBJECT_0+1://线程关闭事件         
begin           
self.Synchronize(DoExitTHrd);          
Break;         
end;        
WAIT_TIMEOUT:continue;//等待,继续运行线程       
end;     
end;   
CloseHandle(Fexecuteevent);    
CloseHandle(FCloseEvent);    
if Assigned(FTimer) then    
begin      
FTimer.Enabled:=false;     
FTimer.Free;     
end;  
end;   
线程事件触发:  
procedure TNew_thread.Start;  
begin    
SetEvent(FExecuteEvent);  
end;    
procedure TNew_thread.stopthread;  
begin    
FTimer.Enabled:=False;    
SetEvent(FCloseEvent);  
end;  
//定义基本上完成了。新建一个测试工程,进行线程测试; 
 procedure TForm1.Button5Click(Sender: TObject);  
var   i:integer;  
begin  //创建一个线程队列,    
for i :=low(NewThreadArr)  to high(NewThreadArr) do    
 begin       
NewThreadArr[i]:=TNew_Thread.create(Memo1);       
Combobox1.Items.Add(inttostr(i)+' Thread ID: '+inttostr(NewThreadArr[i].ThreadID));     
end;     
combobox2.Items.AddStrings(combobox1.Items);  
end;   
procedure TForm1.Button6Click(Sender: TObject);  
var   i:integer; 
 begin   
 i:=combobox1.ItemIndex; //执行某个线程    
if i<0 then exit;   
 NewThreadArr[i].Start;
//设置该线程的执行事件信号状态为真,线程就执行一次操作后,重新等待事件的触发;  
end;   
<!--[if !supportEmptyParas]--> <!--[endif]-->
 procedure TForm1.Button7Click(Sender: TObject); 
 var i:integer; 
 begin    
i:=combobox1.ItemIndex;   
 if i<0 then exit;   
 if assigned(NewThreadArr[i]) then 
 begin      
NewThreadArr[i].stopthread;
//设置该线程的执行事件信号状态为真,线程退出事件被触发,线程自动回收。  
//再调用线程执行事件时,已不可能再观察到线程执行的状态了。    
end;  
end;  
  呵~~,描述完成。  
//加入了定时器后,线程会按定时器时间间隔响应事件的执行。。。。。。 
 更多功能,呵~~,没有加入与完善。  

// -_-///居然要我重新排一次版...........

原创粉丝点击