Delphi XE 中的多线程有啥新功能?

Posted

技术标签:

【中文标题】Delphi XE 中的多线程有啥新功能?【英文标题】:What is new in multithreading in Delphi XE?Delphi XE 中的多线程有什么新功能? 【发布时间】:2011-12-05 06:20:54 【问题描述】:

前段时间,我看到人们讨论 Delphi XE 中的新多线程,以及 Delphi 由于实现多线程的方式而存在一些“本机”问题的事实。他们推荐一些外部库来替换默认的 Delphi 多线程。

你能告诉我一些文档和最流行的 Delphi XE 多线程库吗? 谢谢

【问题讨论】:

TThread.NameThreadForDebugging 存在于 D2010 中。我不相信 Delphi 附带的线程代码存在任何严重问题。最受欢迎和最好的线程库是OmniThreadLibrary,但@gabr 太谦虚了,不能这么说。 Delphi 在实现线程的方式上没有“原生问题”。自 2003 年以来,我一直在使用基于 TThread 的类,没有任何麻烦。但是,您确实希望从现有的第三方线程框架开始,以节省您的麻烦。 不了解线程的程序员在 Delphi 中会遇到与在 C++ 或几乎任何其他语言中相同的问题。我认为唯一的弱点是 TThread 本身并没有实现你可能希望它实现的所有东西,你必须自己做一些工作,例如构建一个可暂停的工作线程。但正如大卫所说,你不需要重新发明***,只需抓住 OmniThreadLibrary。 谢谢大家。我现在正在阅读经典 Delphi 线程的文档,完成后我将为 Omni Thread lib 做。 @DavidHeffernan,是的,它已修复!在此处查看我的更新信息:tthreadedqueue-not-capable-of-multiple-consumers 【参考方案1】:

[您可以设置线程名称:TThread.NameThreadForDebugging.](正如 David 指出的,在 D2010 中实现)

您可以创建匿名线程(执行匿名函数且不需要 TThread 后代对象的线程):TThread.CreateAnonymousThread

这里讨论了 Delphi 线程框架:

Delphi - Threading Frameworks; How Do I Choose Between the Various Ways to do Threading in Delphi?

【讨论】:

具有讽刺意味的是,如果命名线程非常方便,那么任何人都希望创建一个甚至没有与之关联的函数的匿名线程对象,因为它只是一个闭包(另一个功能)。就我个人而言,我希望我的所有后台线程代码都在从 TThread 派生的类中运行。 @Warren 这种愿望有什么原因吗? Warren,没有人会阻止你 :) 但是,有时匿名后台工作人员就足够了。 这种愿望的原因是,如果没有匿名线程,调试线程就已经很痛苦了。 @Warren,我认为您没有理由不能命名您的临时线程。 TThread.NameThreadForDebugging 是一个类函数,它作用于当前线程恰好是什么。只需在匿名函数中调用它。 (CreateAnonymousThread 用词不当;所有线程在被命名之前都是匿名的,并且默认情况下no线程被命名。)【参考方案2】:

此外,除了已经提到的:

有用于外部线程的 TExternalThread 包装器(可通过 TThread.CurrentThread 类属性访问)。 在 IDE 中调试时,您现在可以freeze and thaw 单个线程。 SyncObjs 单元中有很多新内容:支持condition variables、TLightweightEventTLightweightSemaphoreTSpinLockTSpinWaitTInterlocked 等等...

【讨论】:

【参考方案3】:

我认为您所说的“原生”问题与 TThread 的实现方式无关,而是与 RTL 的其他方面有关:

内存管理器速度非常快且编写良好,但在多核上运行多个并发线程时无法以线性方式扩展; 引用计数类型(如 string动态数组)使用 asm lock 操作码实现原子引用计数(x64 中的 InterlockedDecrement/InterlockedIncrement),这也可能会严重扩展在多线程应用程序上(也就是说,当执行此操作码时,所有内核都会冻结 - 即使较新的 CPU 在这方面取得了进展,RCU 实现可能会更好地扩展)。

所有多线程库都存在这些弱点——即使OTL 也会受到this 的影响。它们从很早的 Delphi 版本开始就存在,并且在 Delphi XE2 中仍然存在。 64 位实现类似(甚至更慢),Mac OS 平台共享相同的实现。

请参阅this other SO question 了解如何在 Delphi 中编写可伸缩的多线程应用程序。

老实说,以上两点只会出现在某些非常特定类型的应用程序中。

因此,如果您了解这些要点,并且不要在线程中滥用内存管理器调用或字符串处理,那么在 Delphi 中无需担心多线程。

【讨论】:

【参考方案4】:

gabr 可能提到了主要的新增功能。剩下的可能是TThread.SynchronizeTThread.Queue 的新重载,它们现在可以执行匿名方法。

【讨论】:

【参考方案5】:

我相信所有新引入的功能都已涵盖。

对于文档部分,这里是经典教程书Martin Harvey. Multithreading - The Delphi Way. 的存档副本阅读后,您很可能会意识到实际上不需要任何贡献的库(可能除了线程池),记住,框架并没有为您简化事情,它们还剥夺了您对细粒度的控制。

【讨论】:

在 CC 中也可以使用:Multithreading - The Delphi way (Update: V 1.1)。还有Multithreading - Async Notification library (V 1.2) @TOndrej,续集! :-) 谢谢!【参考方案6】:

TThreadedQueue 是在 XE 中引入的。

我发现它对于将信息从工作线程传递到主线程或其他消费者线程很有用。最后一部分,有多个消费者线程,不幸的是有问题。 Delphi 2009引入的用于同步访问TThreadedQueue中队列的类TMonitor有一个bug。

这已为 XE2 修复。见tthreadedqueue-not-capable-of-multiple-consumers

【讨论】:

以上是关于Delphi XE 中的多线程有啥新功能?的主要内容,如果未能解决你的问题,请参考以下文章

delphi XE4多线程critical section问题

如果 GIL 存在,Python 中的多线程有啥意义?

delphi 的多线程问题

使用 Qt 的多线程应用程序有啥问题(错误 SIGSEGV)

转:iOS开发者经常用到的多线程都有啥?

Java的多线程有啥用处