Recent

Author Topic: TThread: Resume & Suspend deprecated - replacement option?  (Read 23781 times)

mas steindorff

  • Sr. Member
  • ****
  • Posts: 412
TThread: Resume & Suspend deprecated - replacement option?
« on: October 11, 2011, 04:11:41 am »
I was warned but 0.9.30.2RC1 - 2.4.4 that the symbols Resume and Suspend are deprecated (not recomented for new code)  :o

What's the replacement options? (nothing on wiki comes up in the search)
windows 7/10 - laz 2.0 / 1.2.6 general releases

jwdietrich

  • Hero Member
  • *****
  • Posts: 1005
    • formatio reticularis
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #1 on: October 11, 2011, 08:15:07 am »
This is because of Unix based operating systems like Mac OS X and Linux, where suspend and resume are not supported due to security considerations.

A possible very simple solution may be to use a global boolean variable that tells the thread if it should really execute its task or simply return.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7004
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #2 on: October 11, 2011, 10:13:31 am »
I was warned but 0.9.30.2RC1 - 2.4.4 that the symbols Resume and Suspend are deprecated (not recomented for new code)  :o

What's the replacement options? (nothing on wiki comes up in the search)

Just look in the release notes for 2.4.4 ?

http://wiki.freepascal.org/User_Changes_2.4.4#TThread.Suspend_and_TThread.Resume_have_been_deprecated
\

Shebuka

  • Sr. Member
  • ****
  • Posts: 413
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #3 on: October 11, 2011, 10:55:21 am »
I was warned but 0.9.30.2RC1 - 2.4.4 that the symbols Resume and Suspend are deprecated (not recomented for new code)  :o

What's the replacement options? (nothing on wiki comes up in the search)

Just look in the release notes for 2.4.4 ?

http://wiki.freepascal.org/User_Changes_2.4.4#TThread.Suspend_and_TThread.Resume_have_been_deprecated
\

Quote
For suspending running threads: rewrite so this functionality is no longer needed.
It's really easier to say that to realize...

How can i rewrite my SoundPlayer (http://www.lazarus.freepascal.org/index.php/topic,13909.msg73290.html#msg73290) to not use .Suspend?
Will infinite Execute loop that acquire critical section and check FToPlayAlert consume much (all?) CPU? Maybe i need to play a dozen of sounds in a row and then never play a sound for hours and it will still consume precious CPU time (suspended it consumes like 0).
Must i put it in sleep/wait of some sort?

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7004
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #4 on: October 11, 2011, 01:52:59 pm »

Quote
For suspending running threads: rewrite so this functionality is no longer needed.
It's really easier to say that to realize...

How can i rewrite my SoundPlayer (http://www.lazarus.freepascal.org/index.php/topic,13909.msg73290.html#msg73290) to not use .Suspend?
Will infinite Execute loop that acquire critical section and check FToPlayAlert consume much (all?) CPU? Maybe i need to play a dozen of sounds in a row and then never play a sound for hours and it will still consume precious CPU time (suspended it consumes like 0).
Must i put it in sleep/wait of some sort?

When I cleaned up my own code, I used an TEvent to block the thread, yes.

Shebuka

  • Sr. Member
  • ****
  • Posts: 413
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #5 on: October 11, 2011, 03:55:29 pm »
When I cleaned up my own code, I used an TEvent to block the thread, yes.
Can you share an example? I'm still learning...

Troodon

  • Sr. Member
  • ****
  • Posts: 484
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #6 on: October 11, 2011, 05:02:16 pm »
I cannot help making a comment on this topic. While "deprecated" is supposed to mean "obsolete", on Linux  TThread.Suspend never worked (a far as I can remember), but it did on Windows. This is really disappointing because there is a real need for the thread Suspend and Resume functionalities, on all operating systems. The reference to Java in the Freeepascal wiki points out the reasons why thread Stop should not be used; however, there is a simple workaround for this involving a global boolean variable, which works as expected provided the thread does not hang. It then goes on explaining that Suspend and Resume could be replaced with Wait and Notify; I wonder why those  mechanisms were not implemented in Delphi under the Suspend and Resume monikers. I remember a couple years ago Embarcadero made a decision to put more effort into developing the 64-bit version of the compiler rather than into enhancing multithreading functionality. A thread may hang for unexpected reasons, therefore a mechanism for killing the thread, other than closing the application, should be implemented. Anyway, the issue remains that there are situations where a thread needs to be suspended or else some data/progress will be lost. 
Lazarus/FPC on Linux

garlar27

  • Hero Member
  • *****
  • Posts: 593
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #7 on: October 11, 2011, 06:47:22 pm »
@Troodon

I don't know what problems you had on Linux but the one I had was a deadlock because the Application execution will not stop until all threads are terminated. After many days trying to understand the problem, I found out that some things worked from outside the thread and others don't.

So this is the way I solved the problem:

Code: [Select]
{____________________________________________________________________ IsRuning }
function TRecvThread.IsRuning: Boolean;
begin
   Result := (not Terminated) and (not Suspended);
end; {<--- IsRuning }


{___________________________________________________________________ CanResume }
function TRecvThread.CanResume: Boolean;
begin
   Result := (not IsTerminated) and IsSuspended;
end; {<--- CanResume }


{_______________________________________________________________________ Start }
procedure TRecvThread.Start;
begin
   if CanResume then begin
      FSuspendThread := False;
      Resume;
   end;
end; {<--- Start}


{________________________________________________________________________ Stop }
procedure TRecvThread.Stop;
begin
   if IsRuning then begin
      FSuspendThread := True; // ### PARA CORREGIR HILO EN LINUX!!!
      {$IFDEF WINDOWS}
         Suspend;             // ### PARA CORREGIR HILO EN LINUX!!!
      {$ENDIF}
   end;
end; {<--- Stop }


{_______________________________________________________________ TerminateHilo }
procedure TRecvThread.TerminateHilo;
begin
   FTerminateThread := True;     // ### PARA CORREGIR HILO EN LINUX!!!
   {$IFDEF UNIX}
      { If I don't "start" the thread it won't "Terminate" on Linux  (*_*). The app won't close }
      Start;                  // ### PARA CORREGIR HILO EN LINUX!!!
   {$ENDIF}
   Terminate; { No tiene efecto en LINUX, pero si en WIN32 }
end; {<--- TerminateHilo }




{_____________________________________________________________________ Execute }
procedure TRecvThread.Execute;
begin
   { INITIALIZATIONS
      ...
   }
   { MAIN LOOP }
   while TRUE do begin
      if ({ CONDITION}) and (Terminated or Suspended) then begin
         break;
      end;

      {
      SOME CODE ...
      }

      {$IFDEF UNIX}
      if FSuspendThread then begin // ### PARA CORREGIR HILO EN LINUX!!!
         { The thread won't SUSPEND if I don't do it within the Execute method }
         Suspend;                  // ### PARA CORREGIR HILO EN LINUX!!!
      end;

      if FTerminateThread then begin // ### PARA CORREGIR HILO EN LINUX!!!
         { The thread won't TERMINATE if I don't do it within the Execute method }
         Terminate;               // ### PARA CORREGIR HILO EN LINUX!!!
      end;
      {$ENDIF}
   end; // END WHILE
end; {<--- Execute }

I hope this can help you.
Now I don't know what to do with the new thread behavior. So far this keeps working but ...

mas steindorff

  • Sr. Member
  • ****
  • Posts: 412
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #8 on: October 11, 2011, 07:20:56 pm »
Just look in the release notes for 2.4.4 ?

http://wiki.freepascal.org/User_Changes_2.4.4#TThread.Suspend_and_TThread.Resume_have_been_deprecated
\

mmm... I was under the impression a wiki search of "2.4.4" would have come up with this page.  I guess I should have used google.

this has become an interesting thread on threads  :P
windows 7/10 - laz 2.0 / 1.2.6 general releases

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7004
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #9 on: October 11, 2011, 07:40:19 pm »
I cannot help making a comment on this topic. While "deprecated" is supposed to mean "obsolete", on Linux  TThread.Suspend never worked (a far as I can remember), but it did on Windows. This is really disappointing because there is a real need for the thread Suspend and Resume functionalities, on all operating systems. The reference to Java in the Freeepascal wiki points out the reasons why thread Stop should not be used;

Microsoft doesn't recommend it either, read the remarks for the relevant API function:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686345%28v=vs.85%29.aspx

Troodon

  • Sr. Member
  • ****
  • Posts: 484
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #10 on: October 11, 2011, 08:13:58 pm »
@Troodon
I don't know what problems you had on Linux but the one I had was a deadlock because the Application execution will not stop until all threads are terminated. After many days trying to understand the problem, I found out that some things worked from outside the thread and others don't.

IIRC, there are foreground and background threads. The ones launched from the main (GUI) thread are normally background threads and should be automatically terminated when the application exits (main form closes). Only foreground threads can prevent the application from quitting.

Update: I wanted to attach an example application but even in compressed format the file size is larger than the maximum allowed value of 192 KB.
« Last Edit: October 12, 2011, 02:03:06 am by Troodon »
Lazarus/FPC on Linux

Troodon

  • Sr. Member
  • ****
  • Posts: 484
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #11 on: October 11, 2011, 08:17:53 pm »
Microsoft doesn't recommend it either, read the remarks for the relevant API function:

I am aware of that recommendation and I agree with the reasons behind it. All I am saying is, irrespective of the limitations of those specific functions in the API, the means to suspend/resume/terminate a thread programmatically remains an unmet need.
Lazarus/FPC on Linux

jwdietrich

  • Hero Member
  • *****
  • Posts: 1005
    • formatio reticularis
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #12 on: October 12, 2011, 08:33:44 am »
In developing SimThyr, I had a similar problem.

I solved it (perhaps suboptimally, but working) by defining a global variable called haltsim. If it is true the thread does nothing and simply returns, if it is false the simulation is performed. Haltsim is set to false by clicking the start button and a pause button toggles between false and true.

The abridged simulation thread looks like:

Code: [Select]
procedure TSimulationThread.Execute;
begin
  simready := false;
  while i <= nmax do
    begin
      if not haltsim then
       begin

         {... simulate blocks of feedback control here ...}
         i := i + 1;
      end;
    end;
  simready := true;
end;                           

The futile loop the thread performs if haltsim is set to true has only minimal impact on system performance.

In order to make its usage more transparent I also defined two methods for pausing and resuming the thread:

Code: [Select]
procedure TSimulationThread.Pause;
begin
 haltsim := true;
end;

Code: [Select]
procedure TSimulationThread.Restart;
begin
 haltsim := false;
end;

See http://simthyr.sourceforge.net for full sourcecode.
function GetRandomNumber: integer; // xkcd.com
begin
  GetRandomNumber := 4; // chosen by fair dice roll. Guaranteed to be random.
end;

http://www.formatio-reticularis.de

Lazarus 2.0.2 | FPC 3.0.4 | PPC, Intel, ARM | macOS, Windows, Linux

mas steindorff

  • Sr. Member
  • ****
  • Posts: 412
Re: TThread: Resume & Suspend deprecated - replacement option?
« Reply #13 on: October 12, 2011, 08:38:08 pm »
I use .Suspend during the formDestroy code to try and stop the error on exit I would get.  The thread accesses hardware and it takes a little bit to shut things down right.

in the ThreadX.Execute I only have the line
Code: [Select]
...
  while (not Terminated) do begin 
     ...  // access hardware as needed
     sleep(30); 
  end;
...

and in the main code:
Code: [Select]
procedure TfrmCommCntr.FormDestroy(Sender: TObject);
var i:integer;
begin
  MyThComObj.Suspend;
  MyComObj.OnPassPacket := nil;  // new packets come in here
  MyComObj.OnShowStatus := nil;
 ...
  MyComObj.Terminate;
 ...
     // may not be needed but is in Delphi
  WaitForThreadTerminate(MyComObj.Handle,1000);
  MyComObj.Free;
end;   
It's still working so I have not seen if I can simplify it yet.  I may have incomplete code here (regarding .Suspend) so suggestions welcome.
windows 7/10 - laz 2.0 / 1.2.6 general releases