gpt4 book ai didi

multithreading - Delphi队列和同步

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

我正在网上阅读 Nick Hodges 的文章,我发现了队列,但它的行为并不像我预期的那样,我无法理解他和文档所说的内容。看一下这段代码:

 TThread.CreateAnonymousThread(
procedure
begin

TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('start');
end);

Sleep(2000);

TThread.Synchronize(TThread.Current, procedure
begin
Memo1.Lines.Add('end');
end);

end
).Start;

我总是使用Synchronize,但这次我尝试使用Queue,因为根据 Nick 的说法,在多个请求的情况下效果更好,因为它们不会被“序列化”并一一处决。上面的代码工作正常。为什么这不起作用?

 TThread.CreateAnonymousThread(
procedure
begin

TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Clear;
Memo1.Lines.Add('start');
end);

Sleep(2000);

TThread.Queue(TThread.Current, procedure
begin
Memo1.Lines.Add('end');
end);

end
).Start;

在这种情况下,备忘录输出开始,但不输出结束。当我打电话时:

  • 在第一个上同步,在第二个上同步
  • 在第一个上排队,在第二个上同步
  • 排队两次都不起作用,因为我在备忘录中只看到开始

最佳答案

队列和同步的区别在于Synchronize()将调用放入队列并等待该调用完成 Queue()将调用放入队列中并直接将控制权返回给线程。

但是......官方文档中没有提到,当线程完成时,所有调用都会通过 Queue(AThread, AMethod) 放入队列中,其中 AThread 是其自己的线程,已被删除。

您可以在 TThread.Destroy() 的源代码中清楚地看到这一点,其中 RemoveQueuedEvents(Self)被调用。

RemoveQueuedEvents removes queued method calls. [...] If AThread is specified, then all method calls queued by this thread are removed.

因此,在您的最后一个Queue()之后,您的线程结束,TThread.Destroy()将被执行,并且最后一个调用将从队列中删除.

您可以采取一些措施来解决此问题。

  • 就像评论中提到的,您可以调用TThread.Queue(nil, AMethod)。顺便提一句。调用 TThread.Queue(AMethod)TThread.Queue(Self, AMethod) 相同,因此如果线程正在运行,您始终需要使用 nil 变体结束并且您希望通话结束。
  • 但是...如果在执行调用时仍然需要线程处于事件状态(对于其中的某些数据),则需要阻止线程退出。您可以使用 Synchronize() 作为最后一个队列方法来做到这一点。请注意,最后一次同步不必是真正的过程。您可以在 TThread.Execute 末尾调用同步虚拟过程,例如 Synchronize(DummySync) ( example )。队列是 FIFO 的,因此线程将等待,直到队列中的所有调用都被处理(包括空的 dummysync)。

可以在这些页面上找到一些额外信息
Ensure all TThread.Queue methods complete before thread self-destructs
http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/

关于multithreading - Delphi队列和同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42280937/

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