Suspend and Resume are actually executed by the operating system. For Windows, SuspendThread and ResumeThread are called inside these methods .
Functions "very much alive", but ... you really shouldn't use them. The problem is that they work with the flow "here and now." That is, if the Suspend command finds a stream in the middle of an operator (for example, assigning a string), then it is at this point that the stream will fall asleep.
Naturally, such "arbitrariness" does not contribute to the high-quality execution of the application, especially if the additional and main stream work on shared (joint) data. For example, the additional stream began to change the array (string, list, etc.), at this time it was "fallen asleep", the main thread reset the array and woke up the additional one. In the additional stream, the nominal dimension check has already been passed, so he does not know that the element on which the stream is trying to work is no longer there. As a result - guaranteed damage to memory with all the ensuing consequences.
That is why you need to use synchronization objects: TCriticalSection , TMutex , TEvent , TSemaphore , TMultiReadExclusiveWriteSynchronizer , which TMultiReadExclusiveWriteSynchronizer access to shared resources and / or send "correct", at "right times" control signals. An alternative (non-cross-platform) is to use a message mechanism .
As an example: an additional thread must perform some work on a command and wait for a new command:
uses System.SyncObjs; type TmyThread = class(TThread) private FEvent: TEvent; // "синхронизатор" procedure DoWork; // в этом методе будет выполняться полезная работа protected procedure Execute; override; public constructor Create; destructor Destroy; override; procedure StartSingleWork; // этот метод вызывается "извне" end; { TmyThread } constructor TmyThread.Create; begin inherited Create(False); FEvent := TEvent.Create; // создаем сигнальное событие end; procedure TmyThread.Execute; begin while not Terminated do begin FEvent.WaitFor; // ожидаем, пока взведут событие FEvent.ResetEvent; // сбрасываем событие,чтобы // опять войти в ожидание на WaitFor if not Terminated then // и если поток не уничтожают DoWork; // делаем свое дело. end; end; procedure TmyThread.StartSingleWork; begin // кто-то извне хочет, чтобы поток выполнил свою работу FEvent.SetEvent; // выводим поток из спячки. // поток будет выведен из ожидания в WaitFor, // выполнит полезную работу и опять заснет. end; procedure TmyThread.DoWork; begin // здесь выполняется какая-то полезная работа // в контексте нашего дополнительного потока. end; destructor TmyThread.Destroy; begin Terminate; // начинаем уничтожение FEvent.SetEvent; // выводим поток из спячки while not Finished do // ждем, пока он завершится Sleep(0); FreeAndNil(FEvent); // и уничтожаем содержимое потока. inherited; end;
In addition: in my opinion, the best of the articles about multithreading in Delphi (and not only). Unfortunately, only in web.archive ...
Upd. Vinhrad's old forum came to life, direct link to the article