26

I have seen some time ago people discussing about the new multithreading in Delphi XE and about the fact that Delphi has some 'native' problems because of the way it implements multithreading. And they were recommending some external libraries to replace the default Delphi multithreading.

Can you point me to some documentation and the most popular multithreading library for Delphi XE? Thanks

Charles
  • 50,943
  • 13
  • 104
  • 142
Gabriel
  • 20,797
  • 27
  • 159
  • 293
  • I remembered one of the new features: under Delphi XE you can name a thread. Cool. There are others? – Gabriel Oct 11 '11 at 12:15
  • 7
    `TThread.NameThreadForDebugging` exists in D2010. I don't believe there are any serious problems with the threading code that ships with Delphi. The most popular and best threading library is [OmniThreadLibrary](http://otl.17slon.com/) but @gabr is too modest to say so. – David Heffernan Oct 11 '11 at 12:40
  • 1
    Delphi has no "native problems" with the way it implements threading. I have been using classes based on TThread since 2003 without any real hassles. However, you do want to start with an existing third-party threading framework anyway to save yourself the hassle. – Misha Oct 11 '11 at 12:53
  • 3
    Programmers who fail to learn about threading will have the same problems in Delphi as they would in C++, or almost any other language. The only thing I see as a weakness, is that TThread itself doesn't implement everything you might wish it implemented, you have to do a little work yourself, to build a pausable worker thread, for example. But as David says, you needn't reinvent the wheel, just grab OmniThreadLibrary. – Warren P Oct 11 '11 at 13:01
  • 1
    Thanks everybody. I am reading documentation for classic Delphi threads now and when done I will do for Omni Thread lib. – Gabriel Oct 11 '11 at 13:42
  • 1
    For OmniThreadLibrary, start here: http://otl.17slon.com/tutorials.htm in the "High-level primitives" section. – gabr Oct 11 '11 at 14:44
  • 1
    Anyone know if `TMonitor` has been fixed in XE2? – David Heffernan Oct 11 '11 at 15:30
  • 2
    @DavidHeffernan, yes it's fixed ! See my updated information here : [tthreadedqueue-not-capable-of-multiple-consumers](http://stackoverflow.com/questions/4856306/tthreadedqueue-not-capable-of-multiple-consumers) – LU RD Oct 11 '11 at 15:55
  • 1
    Has XE got yet a TForm.OnThreadMessage(threadMsg:TObject) event yet? If not, why not - it's been needed for 25 years, that, and the deprecation of TThread.Synchronize, TThread.WaitFor and TThread.OnTerminate. – Martin James Oct 11 '11 at 16:50
  • 1
    @Martin, No, but OmniThreadLibrary has it. – gabr Oct 11 '11 at 16:52

6 Answers6

28

[You can set thread name: TThread.NameThreadForDebugging.] (implemented in D2010 as David pointed out)

You can create anonymous thread (a thread that executes anonymous function and doesn't need a TThread descendant object): TThread.CreateAnonymousThread.

Delphi threading frameworks are discussed here:

Kromster
  • 7,181
  • 7
  • 63
  • 111
gabr
  • 26,580
  • 9
  • 75
  • 141
  • Ironic that if naming threads is so handy, that anyone would want to create an anonymous thread object that doesn't even have a function associated with it since it's just a closure (a block of code inside another function). Personally I want all my background thread code to be running from inside a class that descends from TThread. – Warren P Oct 11 '11 at 12:59
  • 1
    @Warren Is there a reason for that desire? – David Heffernan Oct 11 '11 at 13:37
  • 1
    Warren, nobody is stopping you :) However, there are times when a anonymous background worker suffices. – gabr Oct 11 '11 at 14:11
  • The reason for that desire is that debugging threads is painful enough without anonymous threadlets. – Warren P Oct 11 '11 at 15:11
  • @WarrenP Why do anonymous procs make debugging harder? You can still break in them. – David Heffernan Oct 11 '11 at 15:55
  • 2
    @Warren, I see no reason you couldn't name your ad-hoc threads. TThread.NameThreadForDebugging is a class function that acts on whatever the current thread happens to be. Simply call it within the anonymous function. (CreateAnonymousThread is a misnomer; *all* threads are anonymous until they're named, and *no* threads are named by default.) – Rob Kennedy Oct 11 '11 at 16:48
  • @Warren, depends on you approach to threading. By using high-level stuff from OtlParallel, using anonymous methods for threading makes lots of sense. – gabr Oct 11 '11 at 16:50
16

Also, in addition to what's already been mentioned:

Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
14

I think the "native" issues you are talking about are not related to the way TThread is implemented, but to other aspects of the RTL:

  • The memory manager is very fast and well written, but it fails to scale in a linear way when running with a number of concurrent threads on multiple cores;
  • Reference-counted types (like string and dynamic arrays) are implemented with an asm lock opcode to have atomic reference counting (InterlockedDecrement/InterlockedIncrement in x64), which may also scale badly on multi-threaded applications (that is, all cores freezes when this opcode is executed - even if newer CPUs made progress about this, an RCU implementation may scale better).

Those weakness are common to all multi-thread libraries - even OTL will suffer about this. They do exist since very early Delphi versions, and are still there with Delphi XE2. The 64 bit implementation is similar (even slower), and the Mac OS platform shares the very same implementation.

Please see this other SO question about how to write scaling multi-threaded applications in Delphi.

To be honest, both points above will appear only on some very specific kind of applications.

So there is nothing to worry about multi-threading in Delphi, if you know those points, and do not abuse of memory manager calls or string process in your threads.

Community
  • 1
  • 1
Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
8

gabr probably mentioned main new additions. What was left probably is the new overloads for TThread.Synchronize and TThread.Queue which can now execute anonymous methods.

Kromster
  • 7,181
  • 7
  • 63
  • 111
Linas
  • 5,485
  • 1
  • 25
  • 35
7

I believe all of newly introduced features were covered already.

For the documentation part, here is an archived copy on classic tutorial book Martin Harvey. Multithreading - The Delphi Way. After reading you will most likely realize what there is no real need for any contributed libraries (except, maybe, the thread pool), remember, frameworks are not simplifying things for you, they also depriving you from the fine-grain control.

Premature Optimization
  • 1,917
  • 1
  • 15
  • 24
  • 1
    Also available in CC: [Multithreading - The Delphi way (Update: V 1.1)](http://cc.embarcadero.com/Item/14809). Also [Multithreading - Async Notification library (V 1.2)](http://cc.embarcadero.com/Item/21570) – Ondrej Kelle Oct 11 '11 at 17:39
5

TThreadedQueue was introduced in XE.

I find it useful for passing information from worker threads to the main thread or other consumer threads. The last part, having multiple consumer threads, was buggy unfortunately. There was a bug in TMonitor, a class introduced by Delphi 2009, used to synchronize access to the queue in TThreadedQueue.

This has been fixed for XE2. See tthreadedqueue-not-capable-of-multiple-consumers

Community
  • 1
  • 1
LU RD
  • 34,438
  • 5
  • 88
  • 296