多线程 一个主窗体创建一个主要线程,再在主要线程中创建N个子线程其中用到临界区,自定义消息,线程之间发消息,主窗体之间消息通知处理此技术可以满足大多数 坛友 想要的Windows平台开发多线程技术可以满足楼主需要的,下面是我写的单元,与调用窗体------------------------------------------------------------------------线程单元unit uDFW;interfaceuses Windows,Messages,Classes;type //主体 TNewThread = class(TThread) private { Private declarations } FStart,FEnd,FCount:Integer;
FList:TList;
FSumQty :Integer;
FRT :TRTLCriticalSection;
FHandle :THandle;//主窗体句柄 protected procedure Execute;
override;
public constructor Create(iStart,iEnd,iCount,iHandle:Integer);overload;
destructor Destroy;override;
end;
//执行 TExecThread = class(TThread) private { Private declarations } FStart,FEnd:Integer;
FThreadID:Cardinal;
protected procedure Execute;
override;
public constructor Create(iStart,iEnd,iThreadID:Integer);overload;
destructor Destroy;override;
end;
const WM_Finished = WM_USER + $2001;//子线程完成向主线程发消息 Wm_FinishedMain = WM_USER + $2002;//主线程向主窗体发完成消息 WM_FinishedChild = WM_USER + $2003;//主线程通知子线程销毁 WM_FinishedClose = WM_USER + $2003;//主窗体关闭时彻底释放主线程implementation{ TNewThread }constructor TNewThread.Create(iStart, iEnd, iCount, iHandle: Integer);
begin
FreeOnTerminate := True;
FStart := iStart;
FEnd := iend;
FCount := iCount;
FHandle := iHandle;
FList := TList.Create;
InitializeCriticalSection(FRT);
inherited Create(False);
end;
destructor TNewThread.Destroy;
begin
FList.Free;
DeleteCriticalSection(FRT);
inherited Destroy;
end;
procedure TNewThread.Execute;var tmpStart,tmpEnd,i,tmp:Integer;
ct:TExecThread;
Msg:TMsg;
begin
{ Place thread code here } tmpStart := FStart;
tmpEnd := 0;
tmp := (FEnd - FStart) div FCount;
for i:= 1 to FCountdo
begin
tmpEnd := tmpEnd + tmp;
if i = FCount then
tmpEnd := Fend;
ct := TExecThread.Create(tmpStart,tmpEnd,ThreadID);
tmpStart := tmpEnd + 1;
FList.Add(ct);
end;
while not Terminateddo
begin
for i:= 0 to FList.Count - 1do
begin
if PeekMessage(MSG,0,WM_Finished,WM_Finished,PM_REMOVE) then
begin
if (Msg.message = WM_Finished) then
begin
if TExecThread(FList.Items).ThreadID = Msg.lParam then
begin
while PostThreadMessage(Msg.lParam,WM_FinishedChild,ThreadID,0)do
begin
Sleep(500);
end;
EnterCriticalSection(FRT);
FSumQty := FSumQty + Msg.wParam;
FList.Delete(i);
LeaveCriticalSection(FRT);
if FList.Count = 0 then
begin
while PostMessage(FHandle,WM_FinishedMain,FSumQty,ThreadID)do
begin
Sleep(500);
end;
end;
Break;
end;
end;
end;
end;
if PeekMessage(MSG,0,WM_FinishedClose,WM_FinishedClose,PM_REMOVE) then
begin
Terminate;
Break;
end;
end;
end;
{ TExecThread }constructor TExecThread.Create(iStart, iEnd,iThreadID: Integer);
begin
FreeOnTerminate := True;
FStart := iStart;
FEnd := iend;
FThreadID := iThreadID;
inherited Create(False);
end;
destructor TExecThread.Destroy;
begin
inherited Destroy;
end;
procedure TExecThread.Execute;var i,SumQty:Integer;
MSG :TMsg;
begin
inherited;
SumQty := 0;
for i:= FStart to FEnddo
SumQty := SumQty + i;
while not Terminateddo
begin
while PostThreadMessage(FThreadID,WM_Finished,SumQty,ThreadID)do
begin
Sleep(500);
if PeekMessage(MSG,0,WM_FinishedChild,WM_FinishedChild,PM_REMOVE) then
begin
if MSG.wParam = FThreadID then
begin
Terminate;
Break;
end;
end;
end;
end;
end;
end.
------------------------------------------------------------------------主窗体.DFM-------------------------------------------------------------------------object Form1: TForm1 Left = 680 Top = 275 Width = 489 Height = 190 Caption = 'Form1' Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'MS Sans Serif' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Label4: TLabel Left = 31 Top = 122 Width = 24 Height = 13 Caption = '和值' end object Label1: TLabel Left = 20 Top = 28 Width = 36 Height = 13 Caption = '起始数' end object Label2: TLabel Left = 23 Top = 62 Width = 36 Height = 13 Caption = '截止数' end object Label3: TLabel Left = 24 Top = 92 Width = 36 Height = 13 Caption = '线程数' end object Button1: TButton Left = 200 Top = 118 Width = 60 Height = 25 Caption = '计算' TabOrder = 0 OnClick = Button1Click end object Edit1: TEdit Left = 63 Top = 21 Width = 121 Height = 21 TabOrder = 1 end object Edit2: TEdit Left = 63 Top = 56 Width = 121 Height = 21 TabOrder = 2 end object Edit3: TEdit Left = 64 Top = 87 Width = 121 Height = 21 TabOrder = 3 end object Edit4: TEdit Left = 64 Top = 119 Width = 121 Height = 21 Enabled = False TabOrder = 4 endend-------------------------------------------------------------------------主窗体.PAS------------------------------------------------------------------------unit frmDFW;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uDFW;type TForm1 = class(TForm) Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Label4: TLabel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private { Private declarations } CurrThreadID :Cardinal;
procedure WMFinishedMain(var msg:TMessage);message WM_FinishedMain;
public { Public declarations } end;
var Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var tt:TNewThread;
iStart,iEnd,iCount:Integer;
begin
try Edit4.Text := '';
iStart := StrToIntDef(Edit1.Text,0);
iEnd := StrToIntDef(Edit2.Text,0);
iCount := StrToIntDef(Edit3.Text,0);
tt := TNewThread.Create(iStart,iEnd,iCount,Handle);
CurrThreadID := tt.ThreadID;
except on e:Exceptiondo
ShowMessage(e.Message);
end;
end;
procedure TForm1.WMFinishedMain(var msg: TMessage);
begin
if msg.Msg = WM_FinishedMain then
begin
if CurrThreadID = msg.LParam then
begin
Edit4.Text := IntToStr(msg.WParam);
PostThreadMessage(CurrThreadID,WM_FinishedClose,0,0);
end;
end;
end;
end.
-------------------------------------------------------------------------------工程.dpr-----------------------------------------------------------------------------program DFW;uses Forms, frmDFW in 'frmDFW.pas' {Form1}, uDFW in 'uDFW.pas';{$R *.res}begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.