Kir*_*ito 6 delphi multithreading
我在delphi中遇到多线程问题.我有一个名单(大约有2000个名字),我需要在我的网站上获取每个名字的一些数据.除线程控制外,我的系统工作正常.
我想创建10个线程,当某个线程终止时,创建另一个...直到列表的末尾.
var
Form1: TForm;
tCount: Integer; //threads count
implementation
type
TCheck = class(TThread)
public
constructor Create(Name: string);
destructor Destroy; Override;
protected
procedure Execute; Override;
end;
MainT = class(TThread)
protected
procedure Execute; Override;
end;
destructor TCheck.Destroy;
begin
Dec(tCount);
end;
procedure MainT.Execute;
var
i: Integer;
Load: TStringList;
begin
Load:=TStringList.Create;
Load.LoadFromFile('C:\mynames.txt');
for i:= 0 to Load.Count -1 do
begin
if tCount = 10 then //if we have 10 threads running...
begin
repeat
Sleep(1);
until tCount < 10;
end;
TCheck.Create(Load.Strings[i]);
TCheck.Start;
Inc(tCount);
end;
end; // end of procedure
Run Code Online (Sandbox Code Playgroud)
好吧,我没有放TCheck.Constructor,因为问题是我如何检查创建的线程数.我的意思是,我的软件只是停止,没有任何错误信息,有时检查500个名字,有时150个名字......
对不起英语不好.
这是使用泛型的线程安全队列解决方案。
\n\n定义您想要的消费者线程数、队列深度,然后DoSomeJob从线程运行该过程。
将使用字符串的作业定义为通用过程(在 中CaptureJob)。
当队列为空时,消费者线程将被销毁。该DoSomeJob过程会等待,直到所有作业准备就绪。\n您可以轻松地将其转变为通用工作池,重用线程而不破坏它们。工作项目的通用结构也使它们适合处理不同类型的工作。
请注意,此队列适用于 XE2 及更高版本。如果您使用的是较旧的 delphi 版本,请按照注释中的建议查找类似的线程安全队列。
\n\nuses\n Classes,SyncObjs,Generics.Collections;\n\nType\n\xc2\xa0 TMyConsumerItem = class(TThread)\n\xc2\xa0 private\n\xc2\xa0 \xc2\xa0 FQueue : TThreadedQueue<TProc>;\n\xc2\xa0 \xc2\xa0 FSignal : TCountDownEvent;\n\xc2\xa0 protected\n\xc2\xa0 \xc2\xa0 procedure Execute; override;\n\xc2\xa0 public\n\xc2\xa0 \xc2\xa0 constructor Create( aQueue : TThreadedQueue<TProc>; aSignal : TCountdownEvent);\n\xc2\xa0 end;\n\nconstructor TMyConsumerItem.Create(aQueue: TThreadedQueue<TProc>);\nbegin\n Inherited Create(false);\n Self.FreeOnTerminate := true;\n FQueue := aQueue;\n FSignal := aSignal;\nend;\n\nprocedure TMyConsumerItem.Execute;\nvar\n aProc : TProc;\nbegin\n try\n repeat\n FQueue.PopItem(aProc);\n if not Assigned(aProc) then\n break; // Drop this thread\n aProc();\n until Terminated;\n finally\n FSignal.Signal;\n end;\nend;\n\nprocedure DoSomeJob(myListItems : TStringList);\nconst\n cThreadCount = 10;\n cMyQueueDepth = 100;\nvar\n i : Integer;\n aQueue : TThreadedQueue<TProc>;\n aCounter : TCountDownEvent;\n function CaptureJob( const aString : string) : TProc;\n begin\n Result :=\n procedure\n begin\n // Do some job with aString\n end;\n end;\nbegin\n aQueue := TThreadedQueue<TProc>.Create(cMyQueueDepth);\n aCounter := TCountDownEvent.Create(cThreadCount);\n try\n for i := 1 to cThreadCount do\n TMyConsumerItem.Create(aQueue,aCounter);\n for i := 0 to myListItems.Count-1 do begin\n aQueue.PushItem( CaptureJob( myListItems[i]));\n end;\n finally\n for i := 1 to cThreadCount do\n aQueue.PushItem(nil);\n aCounter.WaitFor; // Wait for threads to finish\n aCounter.Free;\n aQueue.Free;\n end;\nend;\nRun Code Online (Sandbox Code Playgroud)\n\n注意:Ken 解释了为什么你的初始化和线程启动是错误的。该提案展示了一种更好的结构,可以以更通用的方式处理此类问题。
\n| 归档时间: |
|
| 查看次数: |
5405 次 |
| 最近记录: |