Gar*_*cks 15 delphi multithreading
我对编程很新(大约8个月在Delphi中打开和关闭,在这里和那里有一点点Python)我正在购买一些书籍.
我有兴趣学习并发编程和使用Delphi构建多线程应用程序.每当我搜索"多线程Delphi"或"Delphi多线程教程"时,我似乎都会得到相互矛盾的结果,因为有些东西是关于使用某些库(Omnithread库)而其他东西似乎更适合具有更多经验的程序员.
我已经研究了很多关于德尔福的书籍,并且在很大程度上它们似乎有点撇开表面并且没有真正深入研究这个主题.我有一个程序员(他使用c ++)的朋友,他建议我在使用线程时学习底层系统的实际情况,而不是首先在我的程序中跳转到如何实际实现它们.
在Amazon.com上有很多关于并发编程的书籍,但似乎没有一本书是用Delphi制作的.
基本上我需要知道在开始使用线程之前我应该专注于学习的主要内容,如果我能够/应该尝试使用并非专门针对Delphi开发人员的书籍来学习它们(不想混淆自己阅读现在有很多其他语言代码示例的书籍,如果有关于这个主题的任何可靠的资源/书籍,这里的任何人都可以推荐.
Joh*_*ica 20
简短回答
转到OmnyThreadLibrary安装它并阅读网站上的所有内容.
更长的答案
你问了一些信息,所以这里有:
这里有一些东西要读:
http://delphi.about.com/od/kbthread/Threading_in_Delphi.htm
我个人喜欢:多线程 - 德尔福之路.
(虽然很旧,但基础知识仍然适用)
基本原则:
您的基本VCL应用程序是单线程的.
VCL没有考虑多线程构建,而是使用线程支持,以便大多数VCL组件不是线程安全的.
这样做的方法是让CPU等待,所以如果你想要快速应用程序,请注意何时以及如何与VCL通信.
与VCL沟通
您的基本线程是TThread的后代,拥有自己的成员.
这些是每个线程变量.只要你使用这些就没有任何问题.
我最喜欢的与主窗口通信的方式是使用自定义窗口消息并postmessage以异步方式进行通信.
如果要同步通信,则需要使用临界区或synchonize方法.
请参阅此文章,例如:http://edn.embarcadero.com/article/22411
线程之间的通信
这是事情变得棘手的地方,因为你可能遇到各种难以调试的同步问题.
我的建议:使用OmnithreadLibrary,也看到这个问题: Delphi中的跨线程通信
有些人会告诉你,读取和写入整数在x86上是原子的,但这不是100%正确,所以不要以天真的方式使用它们,因为你很可能会得到错误的细微问题并最终难以调试代码.
启动和停止线程
在旧版本的Delphi Thread.suspend和Thread.resume使用,但这些都不再推荐,应当避免(在线程同步的情况下).
看到这个问题:我应该用什么delphi代码替换我对不推荐使用的TThread方法Suspend的调用?
另外看看这个问题,虽然答案更模糊:在Delphi-2010中不推荐使用TThread.resume应该使用什么?
您可以使用suspend和resume暂停和重新启动线程,只是不要将它们用于线程同步.
性能问题
把wait_for...,synchonize在你的线程代码等有效地阻止你的线程,直到它在等待已发生的动作.
在我看来,这打破了线程的一个重要目的:速度
因此,如果你想要快速,你必须要有创意.
很久以前我写了一个名为Life32的应用程序.
它的显示程序conways game of life.这可以非常快速地生成模式(在小模式上每秒数百万代).
它使用单独的线程进行计算,并使用单独的线程进行显示.
显示是一个非常慢的操作,不需要每一代都完成.
生成线程包括显示代码,用于从显示中删除内容(在视图中时),显示线程只是设置一个布尔值,告诉生成线程也显示添加的内容.
生成代码使用DirectX直接写入视频内存,不需要VCL或Windows调用,也不进行任何同步.
如果移动主窗口,应用程序将继续显示在旧位置,直到您暂停生成,从而停止生成线程,此时更新线程变量是安全的.
如果线程没有100%同步,显示发生的时间太晚了,没什么大不了的.
它还具有自定义内存管理器,可避免标准内存管理器中的线程安全缓慢.通过避免任何和所有形式的线程同步,我能够消除90%+(在小模式上)到0的开销.
Mar*_*mes 15
你真的不应该让我开始这个,但无论如何,我的建议:
尽量不要使用以下内容:
TThread.SynchronizeTThread.WaitForTThread.OnTerminateTThread.SuspendTThread.Resume,(在某些Delphi版本的构造函数末尾除外)TApplication.ProcessMessages使用PostMessageAPI与主线程进行通信 - lParam比如发布对象.
结果将是一个表现良好,不泄漏,不会死锁并在关闭主表单时立即关闭的应用程序.
Delphi应该内置的内容:
TWinControl.PostObject(anObject:TObject)和TWinControl.OnObjectRx(anObject:TObject)-的方法来从辅助线程发布对象,并与他们触发一个主线程事件.一个简单的PostMessage包装来取代表现不佳,产生死锁的,不断重写的TThread.Synchronize.
一个简单的,无限制的生产者 - 消费者类,实际上适用于多个生产者/消费者.这就像20行的TObjectQueue后代,但Borland/Embarcadero无法管理它.如果您有对象池,则不需要复杂的有界队列.
一个简单的线程安全,阻塞,对象池类 - 再次,Delphi非常简单,因为它有类变量和虚拟构造函数,例如.创建了很多缓冲对象:
myPool:=TobjectPool.create(1024,TmyBuffer);
我认为实际尝试编译一个有关多线程的事情清单可能会很有用。
TCriticalSection,TMREWSync,TEventInterlockedIncrement,InterlockedExchange,...当然,这还远未完成。我制作了这个社区Wiki,以便每个人都可以编辑。
| 归档时间: |
|
| 查看次数: |
3053 次 |
| 最近记录: |