1000分求动态创建线程的问题(300)

W

weiliu

Unregistered / Unconfirmed
GUEST, unregistred user!
现在是多核CPU多线程的时代,比如我要计算从1加到10000,如果是双核CPU,这个程序就会自动开两个线程,一个从1加到5000,另一个从5001加到10000,最后将两个线程的结果相加。如果是四核的CPU,这个程序就会开四个线程,每个线程加2500个数。判定CPU几个核或几个线程就不用写了,我只要求在主程序中输入一个需要打开的线程数,这个程序就能据此开几个线程。另外,如果得知每个线程都计算完毕呢?谁能给出代码?谢谢!
 
自己继承个线程类动态创建不就行了? 线程结束有OnTerminate事件TThSum=class(TThread) fx,fy:integer;
public constructor Create(x,y:integer);
//x起始数,y终止数end;
constructor TThSum.Create(x,y:integer);
//x起始数,y终止数begin
fx:=x;
fy:=y;
FreeOnTerminate:=true;
inherited Create(true);
end;
var thsum:TThSum;
i:integer;
x,y:integer;
begin
for i:=0 to 3do
begin
x:= ;
y:= ;
thsum:=TThSum.Create(x,y);
thsum.OnTerminate;=xxxx;
//自己写个OnTerminate函数 作为线程结束通知 thsum.Resume;
end;
end;
 
自己写吧,demo里有例子,线程无非就是定义个全局变量,根据全局变量控制多线程。
 
楼上的程序我看不太明白,你能就按我的意思写上一个小程序吗?输入一个线程数后,它就会创建相应数量的线程,每个线程平均计算从1到10000的加法的一部分,最后把总和算出来。有些人是这样动态创建线程的,那么具体怎么用呢?type TMyThread = class(TThread) ... end;
var i: integer;
Threads: array[0..9] of TMyThread;
begin
for i := Low(Threads) to High(Threads)do
begin
Threads := TThread.Create(False);
... end;
end;
 
to lht123, DEMO里有这样动态创建线程的例子?
 
不是动态创建的
 
建立一个线程数组,动态数组
 
楼上,建立了线程数组后又如何使用呢?
 
线程会用么,就正常使用啊。
 
楼上,你帮我把我需要的代码写出来,我给你1000分如何?绝不食言。
 
以前用过线程 不过真的有点忘记了,代码还是你自己写好,我当时做的是收发短信用的线程,多少分不重要,希望你能先实现一个线程的代码,那么线程数据就可以分配了。以前见过一个人用的是线程数组,好像单核cpu最多能开16个线程。
 
这个其实不是线程的问题,创建多个线程都没有问题,自己建个线程管理器把创建的线程管理起来即可关键是如何把业务分解成可以任意增加线程的,如果楼主解决了这个问题,再来想动态创建线程的问题吧。
 
type TNewThread = class(TThread) private FStart, FEnd: Integer;
FResult: Integer;
protected procedure Execute;
override;
public constructor Create(const AStart, AEnd: Integer);
property Result: Integer read FResult;
end;
constructor TNewThread.Create(const AStart, AEnd: Integer);
begin
FStart:= AStart;
FEnd:= Aend;
inherited Create(False);
end;
procedure TNewThread.Execute;
var Loop: Integer;
begin
FResult:= 0;
if FStart > FEnd then
for Loop := FStartdo
wnto FEnddo
Inc(FResult, Loop) else
for Loop := FStart to FEnddo
Inc(FResult, Loop);
end;
function Sum(const AStart, AEnd, ACount: Integer): Integer;
var Loop, Temp, nStart, nEnd: Integer;
Objs: array of TNewThread;
Obj: TNewThread;
begin
Temp:= Abs(AEnd - AStart) div ACount;
SetLength(Objs, ACount);
Obj:= nil;
nEnd:= 0;
for Loop := 0 to ACount - 1do
begin
nStart:= AStart + Loop * Temp;
nEnd:= nStart + Temp - 1;
if nEnd > AEnd then
nEnd:= Aend;
Objs[Loop]:= TNewThread.Create(nStart, nEnd);
end;
if nEnd <> AEnd then
Obj:= TNewThread.Create(nEnd + 1, AEnd);
Result:= 0;
for Loop := 0 to ACount - 1do
begin
Objs[Loop].WaitFor;
Inc(Result, Objs[Loop].Result);
Objs[Loop].Free;
end;
if Assigned(Obj) then
begin
Inc(Result, Obj.Result);
Obj.Free;
end;
SetLength(Objs, 0);
end;
调用:Edit1.Text:= IntToStr(Sum(1, 10000, 4));
 
多线程 一个主窗体创建一个主要线程,再在主要线程中创建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.
 
如果楼主还想交流,请随时发帖!最近项目轻松又时间研究!
 
能另外开贴为bahamut8348加分吗?算不算违规?
 
顶部