Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with using TThread.Resume? [duplicate]

Long ago, when I started working with threads in Delphi, I was making threads start themselves by calling TThread.Resume at the end of their constructor, and still do, like so:

constructor TMyThread.Create(const ASomeParam: String);
begin
  inherited Create(True);
  try
    FSomeParam:= ASomeParam;
    //Initialize some stuff here...
  finally
    Resume;
  end;
end;

Since then, Resume has been deprecated in favor to use Start instead. However, Start can only be called from outside the thread, and cannot be called from within the constructor.

I have continued to design my threads using Resume as shown above, although I know it's been deprecated - only because I do not want to have to call Start from outside the thread. I find it a bit messy to have to call:

FMyThread := TMyThread.Create(SomeParamValue);
FMyThread.Start;

Question: What's the reason why this change was made? I mean, what is so wrong about using Resume that they want us to use Start instead?

EDIT After Sedat's answer, I guess this really depends on when, within the constructor, does the thread actually begin executing.

like image 278
Jerry Dodge Avatar asked Mar 14 '16 23:03

Jerry Dodge


People also ask

Why * are thread stop thread suspend and thread resume deprecated?

suspend() is deprecated because it is inherently deadlock-prone. As a result, Thread. resume() must be deprecated as well. When the target thread is suspended, it holds a lock on the monitor protecting a crucial system resource, and no other thread may access it until the target thread is resumed.

What is used to resume the suspended thread?

resume(): This is a method used to resume the suspended thread.

How do I write a resume for a thread?

Java Thread resume() methodThe resume() method of thread class is only used with suspend() method. This method is used to resume a thread which was suspended using suspend() method. This method allows the suspended thread to start again.


1 Answers

The short and pithy answer is because the authors of the TThread class didn't trust developers to read or to understand the documentation. :)

Suspending and resuming a thread is a legitimate operation for only a very limited number of use cases. In fact, that limited number is essentially "one": Debuggers

Undesirables

The reason it is considered undesirable (to say the least) is that problems can arise if a thread is suspended while (for example) it owns a lock on some other synchronization object such as a mutex or sempahore etc.

These synchronization objects are specifically designed to ensure the safe operation of a thread with respect to other threads accessing shared resources, so interrupting and interfering with these mechanisms is likely to lead to problems.

A debugger needs a facility to directly suspend a thread irrespective of these mechanisms for surprisingly similar reasons.

Consider for example that a breakpoint involves an implicit (or you might even say explicit) "suspend" operation on a thread. If a debugger halts a thread when it reaches a break-point then it must also suspend all other threads in the process precisely because they will otherwise race ahead doing work that could interfere with many of the low level tasks that the debugger might be asked to then do.

The Strong Arm of the Debugger

A debugger cannot "inject" nice, polite synchronization objects and mechanisms to request that these other thread suspend themselves in a co-ordinated fashion with some other thread that has been unceremoniously halted (by a breakpoint). The debugger has no choice but to strong-arm the threads and this is precisely what the Suspend/Resume API's are for.

They are for situations where you need to stop a thread "Right now. Whatever you are doing I don't care, just stop!". And later, to then say "OK, you can carry on now with whatever it was you were doing before, whatever it was.".

Well Behaved Threads Behave Well Toward Each Other

It should be patently obvious that this is not how a well-behaved thread interacts with other threads in normal operation (if it wishes to maintain a state of "normal" operation and not create all sorts of problems). In those normal cases a thread very much does and should care what those other threads are doing and ensure that it doesn't interfere, using appropriate synchronization techniques to co-ordinate with those other threads.

In those cases, the legitimate use case for Resuming a thread is similarly reduced to just one, single mode. Which is, that you have created and initialised a thread that you do not wish to run immediately but to start execution at some later point in time under the control of some other thread.

But once that new thread has been started, subsequent synchronization with other threads must be achieved using those proper synchronization techniques, not the brute force of suspending it.

Start vs Suspend/Resume

Hence it was decided that Suspend/Resume had no real place on a general purpose thread class (people implementing debuggers could still call the Windows API's directly) and instead a more appropriate "Start" mechanism was provided.

Hopefully it should be apparent that even though this Start mechanism employs the exact same API that the deprecated Resume method previously employed, the purpose is quite different.

like image 200
Deltics Avatar answered Sep 30 '22 17:09

Deltics