The Programming Works

TThread Facts

Posted in Uncategorized by Serg on December 18, 2011

Delphi RTL TThread class has been an object of criticism since its introduction. Some criticism was deserved, some not. TThread implementation was gradually improving with every Delphi version. Here I am neither criticizing nor advocating the TThread class, just listing some details of TThread implementation in modern Delphi versions that Delphi programmer should know.

  1. TThread class does not allow setting a thread stack size – it is always equal to default value, usually 1 Mb. If you need a different value you can call BeginThread function directly, but that is a low level solution and not as handy as using TThread class;
  2. TThread constructor has the only parameter (CreateSuspended: Boolean). Irrespective of the parameter value the underlying Windows thread object is always created in suspended state:
        FCreateSuspended := CreateSuspended {...};
        FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
    

    A thread can start execution in AfterConstruction method (which is called after all inherited constructors):
      if not FCreateSuspended {...} then Resume;
    

    or later;
  3. Synchronization with the main thread does not work in console application. That means that you should not use Synchronize and Queue methods of TThreads class in console application. The same also applies to OnTerminate event which calls Synchronize method internally; you can override protected DoTerminate method instead;
  4. If you set FreeOnTerminate = True for a TThread instance, the instance is destroyed in the context of underlying background thread. Usually the destruction context does not matter, but in some cases it does. For example, create a TTimer instance in the constructor of TThread descendant, destroy timer in the destructor and see what happens (hint: an invisible window of TTimer instance is created in the main thread and destroyed in a different thread);
  5. TThread does not guarantee that Execute method will be called. I have bumped into this problem a little before.

Despite all issues we are better to use TThread class ‘as is’ in GUI applications. For my experiments I have written a simple alternative thread wrapper class that allows setting a thread stack size, always calls Execute method and does not contain synchronization methods; it is well suited for console applications.

Advertisement
Tagged with: , , ,

4 Responses

Subscribe to comments with RSS.

  1. WarrenP said, on December 18, 2011 at 9:29 pm

    The problem is not just in TThread, it is in the brains, or in the lack of brains in delphi developers. After having explained very carefully how TThread.Synchronize can be used, and misused, people continue to misuse and misunderstand it. After understanding the problems in TThread.Suspend/Resume, and its subsequent deprecation, some delphi developers fail to understand the following; That Threads are not simple, and that threading is almost never as easy and straightforward as you might like.

    TThread is not the one source for all your problem solutions related to multi-threaded programming, nor should it be. If you learn to use TCriticalSection properly, learn to use Events and wait for events, instead of using Sleep, and so on…. Perhaps you’ll do better. But whether one uses TThread or does not, is not the problem. The problem is whether or not you realize that multi-thread programming is not a class, it’s a learning process.

    W

  2. himitsu said, on December 18, 2011 at 11:26 pm

    Who uses the VCL directly within a thread, is itself to blame. And that includes TTimer

  3. LDS said, on December 19, 2011 at 11:52 pm

    I posted QC #77203 to ask for a way to set the thread stack size when creating a thread.
    IMHO there’s also another flaw in TThread.WaitFor, because it doesn’t allow a time out (moreover Destroy calls it), if you call it and the thread is stuck the caller will be as well. See QC #9398 (I reported it in 2004… and the fix is simple, I believe)

  4. Rhys Drummond said, on January 20, 2012 at 3:09 am

    @WarrenP: I’d love to learn the ‘right’ way to use threading; can you point us to some resources please?
    TIA


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.