gpt4 book ai didi

multithreading - TThread.Synchronize 是邪恶的/死产的吗?

转载 作者:行者123 更新时间:2023-12-03 18:09:26 25 4
gpt4 key购买 nike

我的印象是,一个应该至少可以从主线程控制的线程根本不能使用 Synchronize():在一种情况下,任何尝试这样做几乎都会立即导致死锁或其他。

因此,onTerminate 事件也应该避免,因为它是使用 Synchronize 调用的。

例如,我有一个线程可以做一些艰苦的后台工作。如果用户按下关闭按钮,我想在状态栏中查看它的进度并能够“优雅地”停止它。

我不能使用 FreeOnTerminate := true,因为当线程启动时,我根本不能调用它的任何方法:在任何时候它都可能被破坏并且我遇到访问冲突(或完全破坏某些东西)。

所以,线程销毁是主线程的责任。在某种 DoTerminate 过程中完成所有“完成”工作并将 onTerminate 事件指向它是合乎逻辑的。但这是死锁:我们无法从 DoTerminate 中释放线程,因为在 TThread.Free 中有 WaitFor 在同步的 onTerminate 事件完成之前无法完成。

不仅仅是 OnTerminate:如果工作线程中有任何 Synchronize 调用在其中(例如,它想通知我们某些百分比的工作已完成等),如果此时主线程正在运行,则可能出现死锁用工作线程做某事:他们互相阻塞!

所以,据我了解,使用 Synchronize 的唯一方法是将所有调用委托(delegate)给工作线程端!例如,我们使用 FreeOnTerminate := true 创建它,它有时使用 Synchronize() 来告诉我们它的进度,或者它已经完成并且将被销毁。只有在这些过程中我们才能控制它,但它使“随意”优雅关闭几乎不可能或过于复杂。

我是否遗漏了什么(一些有助于以某种方式克服这些僵局的内部工作)?因为我有点惊讶: Synchronize() 是 Delphi 多线程手册中描述的第一个方法。真的这么没用吗?

最佳答案

Synchronize 有完全有效的用例,但您必须小心识别这些用例是什么,并确保您正在编写代码,以便明确避免出现死锁的可能性情况。这是完全可能的,但需要仔细设计。

您通常应该只在需要工作线程等待主线程完成工作后再继续工作时使用Synchronize。在大多数情况下,这不是必需的,通常应该优先使用 TThread.Queue 代替。使用 Queue 将工作发布到主线程,然后立即返回,而无需等待主线程处理工作。这避免了围绕使用 Synchronize 的大多数死锁陷阱。

Queue 的唯一危险是主线程重载。如果您的工作人员将工作发布到主线程的速度超过了主线程可以跟上的速度,那么您最终可能会遇到主线程锁定处理排队工作的情况。

关于multithreading - TThread.Synchronize 是邪恶的/死产的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43680844/

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