gpt4 book ai didi

multithreading - 在线程之间同步/发送数据

转载 作者:行者123 更新时间:2023-12-03 14:38:28 25 4
gpt4 key购买 nike

该应用程序是用 Delphi XE 编写的。

我有两个类,TBoss 和 TWorker,它们都基于 TThread。TBoss是一个单实例线程,它启动后会创建大约20个TWorker线程。

当 Boss 创建 TWorker 实例时,它会为其分配一个方法来调用同步,当 Worker 完成其正在执行的操作时,它会调用此方法,该方法允许 Boss 访问 Worker 上的记录。

但是我觉得这是一个问题,调用同步似乎锁定了整个应用程序 - 阻塞主(ui)线程。实际上,它应该只是将该工作人员同步到老板线程......

以前,我使用消息/打包记录在线程之间发送内容,效果很好。然而,这样做更干净、更好......只是非常阻塞。

有没有办法在worker中调用Syncronize来只等待Boss线程?

我的代码:

    type 
TWorker = class(TThread)
private
fResult : TResultRecord;
procedure SetOnSendResult(const Value: TNotifyEvent);
....
....
public
property OnSendResult: TNotifyEvent write SetOnSendResult;
property Result : TResultRecord read fResult;
....
end;

...
...
procedure TWorker.SendBossResults;
begin
if (Terminated = False) then
begin
Synchronize(SendResult);
end;
end;

procedure TWorker.SendResult;
begin
if (Terminated = false) and Assigned(FOnSendResult) then
begin
FOnSendResult(Self);
end;
end;

然后在我的 Boss 线程中我会做这样的事情

    var 
Worker : TWorker;
begin
Worker := TWorker.Create;
Worker.OnTerminate := OnWorkerThreadTerminate;
Worker.OnSendResult := ProcessWorkerResults;

所以我的老板有一个名为 ProcessWorkerResults 的方法 - 这是在 Synchronize(SendResult) 上运行的方法; worker 的。

    procedure TBoss.ProcessWorkerResults(Sender: TObject); 
begin
if terminated = false then
begin
If TWorker(Sender).Result.HasRecord then
begin
fResults.Add(TWorker(Sender).Result.Items);
end;
end;
end;

最佳答案

Synchronize 专门设计用于在线程中执行代码;这就是为什么它似乎锁定了一切。

您可以使用多种方式从工作线程到主线程进行通信:

  • 为每个工作线程添加回调,并从 boss 线程分配它当它被创建时。可以传回来无论作为参数,以及线程 ID 或其他一些标识符。

  • 从工作线程发布消息到老板线程使用 PostThreadMessage 。这这里的缺点是老板线程必须有一个窗口句柄(参见Classes.AllocateHWnd中Delphi 帮助和 David Heffernan 的评论如下)。

  • 使用优质的第三方线程库。看 OmniThreadLibrary - 免费,操作系统,写得非常好。

我的选择是第三个。 Primoz已经为您完成了所有艰苦的工作。 :)

在您发表评论后,这是与我的第一个建议类似的内容。请注意,这是未经测试的,因为为 TBoss 和 TWorker 线程 + 测试应用程序编写代码对于我此刻的时间来说有点长......这应该足以为您提供我希望是要点。

type 
TWorker = class(TThread)
private
fResult : TResultRecord;
fListIndex: Integer;
procedure SetOnSendResult(const Value: TNotifyEvent);
....
....
public
property OnSendResult: TNotifyEvent write SetOnSendResult;
property Result : TResultRecord read fResult;
property ListIndex: Integer read FListIndex write FListIndex;
....
end;

type
TBoss=class(TThread)
private
FWorkerList: TThreadList; // Create in TBoss.Create, free in TBoss.Free
...
end;

procedure TWorker.SendBossResults;
begin
if not Terminated then
SendResult;
end;

procedure TBoss.ProcessWorkerResults(Sender: TObject);
var
i: Integer;
begin
if not terminated then
begin
If TWorker(Sender).Result.HasRecord then
begin
FWorkerList.LockList;
try
i := TWorker(Sender).ListIndex;
// Update the appropriate record in the WorkerList
TResultRecord(FWorkerList[i]).Whatever...
finally
FWorkerList.UnlockList;
end;
end;
end;
end;

关于multithreading - 在线程之间同步/发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5600532/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com