【发布时间】:2017-04-28 12:59:12
【问题描述】:
我的印象是,应该至少可以从主线程控制的线程根本不能使用Synchronize():任何尝试这样做几乎都会立即导致死锁。
因此,onTerminate 事件也应该避免,因为它是使用 Synchronize 调用的。
例如,我有一个线程可以做一些艰苦的后台工作。如果用户按下关闭按钮,我想在状态栏中查看它的进度并能够“优雅地”停止它。
我不能使用FreeOnTerminate := true,因为当线程启动时,我根本不能调用它的任何方法:在任何时候它都可能被破坏并且我会遇到访问冲突(或完全破坏某些东西)。
所以,线程销毁是主线程的责任。在某种 DoTerminate 过程中完成所有“完成”工作并将 onTerminate 事件指向它是合乎逻辑的。但这是死锁:我们无法从 DoTerminate 中释放线程,因为在 TThread.Free 中有 WaitFor 在同步的 onTerminate 事件完成之前无法完成。
不仅仅是 OnTerminate:如果工作线程中有任何 Synchronize 调用(例如,它想通知我们已经完成了某些百分比的工作等),如果此时主线程正在运行,则可能出现死锁用工作线程做某事:他们互相阻塞!
所以,据我了解,使用 Synchronize 的唯一方法是将所有调用委托给工作线程端!例如,我们使用FreeOnTerminate := true 创建它,它有时使用 Synchronize() 来告诉我们它的进度,或者它已经完成并且将被销毁。只有在这些过程中我们才能控制它,但它使“随意”优雅关闭几乎不可能或过于复杂。
我是否遗漏了什么(一些有助于以某种方式克服这些僵局的内部工作)?因为我有点惊讶: Synchronize() 是 Delphi 多线程手册中描述的第一种方法。真的这么没用吗?
【问题讨论】:
-
你能发布你的代码吗?我在这里试过,效果很好。
-
为什么这个问题被否决了?没有示例代码,我完全理解这一点。
-
Synchronize本身不是问题。程序架构是。例如,在持有临界区气味的同时调用 Synchronize(这 可以 没问题......但更可能是灾难的根源)。 Synchronize 的问题在于如何让线程相互通信。
标签: multithreading delphi synchronization