use*_*691 -1 delphi multithreading
现在有一个像这样的多线程方案:
//global variables
var
Form1: TForm1;
ControlFile: TextFile;
MaxThreads, iThreads: integer;
MyCritical: TCriticalSection;
Run Code Online (Sandbox Code Playgroud)
ControlFile由执行ReadLn的线程访问,并使用获得的行执行操作:
procedure TForm1.Button2Click(Sender: TObject);
var
HostLine: AnsiString;
FileHandle: integer;
begin
MyCritical:= TCriticalSection.Create;
MaxThreads:= 100;
iThreads:= 0;
while not(eof(ControlFile)) and (iThreads < MaxThreads) do
begin
inc(iThreads);
ReadLn(ControlFile, HostLine);
MyThread.Create(HostLine);
end;
end;
Run Code Online (Sandbox Code Playgroud)
这个街区是第一个疑问.我创建了100个线程,每个创建的线程接收到文本文件的当前行.但问题是在threads.onterminate上,我执行:
procedure MyThread.MainControl(Sender: TObject);
var
HostLine: string;
begin
try
MyCritical.Acquire;
dec(iThreads);
while not(eof(ControlFile)) and (iThreads < MaxThreads) do
begin
inc(iThreads);
ReadLn(ControlFile, HostLine);
MyThread.Create(HostLine);
end;
finally
MyCritical.Release;
end;
end;
Run Code Online (Sandbox Code Playgroud)
我们的想法是继续创建新线程,直到文本文件完成.但是如果一个线程终止并执行此过程,那么在第一个完成之前,会发生什么?来自button2click的主线程将访问该文件,以及线程的过程.这看起来很奇怪.而关键部分应该是全局的还是本地的线程?这个程序MainControl在文件结束之前打开新线程应该是全局的还是线程本地的?
首先,我不确定从同一个文本文件中读取不同的线程是一个如此出色的想法.这并不是说它无法工作,但我认为将整个事物简单地预先读入TStringList变量会更加清晰,然后可以在线程之间共享,如果需要的话.
如果你确实使用了你已有的东西,你的关键部分也必须在主循环中获取 - 你生成的线程默认会立即开始执行,所以看起来主线程和线程之间可能存在竞争运行MainControl,虽然你没有准确显示该调用将如何进行.
关键部分需要是全局变量,或者是全局类的字段/属性,以便在线程之间共享.
我的最后一点是,创建100个线程可能不是最好的主意.除非您的线程主要等待I/O或事件,否则通常不应该拥有比CPU内核更多的线程.最好使用一个工作线程池和一个工作项队列,然后可以将它们发送到正在运行的线程.据说在最近的Delphi RTL中有一些内置的支持.我个人使用自己尝试过的自定义线程池实现,所以我不能给你任何特定的帮助.
| 归档时间: |
|
| 查看次数: |
534 次 |
| 最近记录: |