Recent

Author Topic: How would you manage this thread related problem?  (Read 1090 times)

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
How would you manage this thread related problem?
« on: September 07, 2023, 04:39:34 pm »
I would ask help to understand how to make the last case ('hang') work.

With the last case commented, program ends, it shows no "error", and enabling the Heaptrc unit shows that there is no memory leak.

If I enable the last case program does not end, and I wonder how I can make it end and have no memory leaks as in first three cases.
Thanks

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses
  4.  
  5.   cthreads,
  6.   Classes, SysUtils;
  7.  
  8. type
  9.  
  10.   TLocalThread = class(TThread)
  11.     protected
  12.       procedure Execute(); override;
  13.     public
  14.       Action: string;
  15.   end;
  16.  
  17. procedure TLocalThread.Execute();
  18. begin
  19.   Sleep(100);
  20.  
  21.   if Action = 'trapped exception' then
  22.   begin
  23.     Writeln('trapped exception');
  24.     try
  25.       raise Exception.Create('TLocalThread trapped exception');
  26.     except
  27.       on E: Exception do
  28.       begin
  29.         Writeln(E.Message);          
  30.       end;
  31.     end;
  32.   end
  33.   else if Action = 'untrapped exception' then
  34.   begin
  35.     Writeln('untrapped exception');
  36.     raise Exception.Create('TLocalThread untrapped exception');
  37.   end
  38.   else if Action = 'hang' then
  39.   begin
  40.     Writeln('hang');
  41.     while (True) do Sleep(100);
  42.   end
  43.   else begin
  44.     Writeln('success');
  45.   end;
  46. end;
  47.  
  48. var
  49.   tsuccess, ttrappedexception, tuntrappedexception, {%H-}thang: TLocalThread;
  50. begin
  51.   {%region 'success'}
  52.   Writeln('TESTING success === START');
  53.   tsuccess := TLocalThread.Create(True);
  54.   try
  55.     tsuccess.Action := ''; // success
  56.     tsuccess.Start();
  57.  
  58.     Sleep(3000);
  59.   finally
  60.     Sleep(500);
  61.     tsuccess.Free();
  62.   end;
  63.   Writeln('TESTING success === END');
  64.   {%endregion}
  65.   {%region 'trapped exception'}
  66.   Writeln('TESTING trapped exception === START');
  67.   ttrappedexception := TLocalThread.Create(True);
  68.   try
  69.     ttrappedexception.Action := 'trapped exception';
  70.     ttrappedexception.Start();
  71.  
  72.     Sleep(3000);
  73.   finally
  74.     Sleep(500);
  75.     ttrappedexception.Free();
  76.   end;
  77.   Writeln('TESTING trapped exception === END');
  78.   {%endregion}
  79.   {%region 'untrapped exception'}
  80.   Writeln('TESTING untrapped exception === START');
  81.   tuntrappedexception := TLocalThread.Create(True);
  82.   try
  83.     tuntrappedexception.Action := 'untrapped exception';
  84.     tuntrappedexception.Start();
  85.  
  86.     Sleep(3000);
  87.   finally
  88.     Sleep(500);
  89.     tuntrappedexception.Free();
  90.   end;
  91.   Writeln('TESTING untrapped exception === END');
  92.   {%endregion}
  93.   {%region 'hang'}
  94.   //Writeln('TESTING hang === START');
  95.   //thang := TLocalThread.Create(True);
  96.   //try
  97.   //  thang.Action := 'hang';
  98.   //  thang.Start();
  99.   //
  100.   //  Sleep(3000);
  101.   //finally
  102.   //  KillThread(thang.ThreadID);
  103.   //  Sleep(500);
  104.   //  thang.Free();
  105.   //end;
  106.   //Writeln('TESTING hang === END');
  107.   {%endregion}
  108. end.
  109.  

NOTE: in original post this line was missing:
Code: Pascal  [Select][+][-]
  1. KillThread(thang.ThreadID);
  2.  

I added afterwards hoping it could solve, but still it doesn't work, it remains hang forever.
« Last Edit: September 07, 2023, 04:49:40 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

paweld

  • Hero Member
  • *****
  • Posts: 1611
Re: How would you manage this thread related problem?
« Reply #1 on: September 07, 2023, 05:20:23 pm »
use [Thread.Terminate
Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses
  4.   {$IFDEF UNIX}{$IFDEF UseCThreads}cthreads, {$ENDIF}{$ENDIF}
  5.   Classes, SysUtils;
  6.  
  7. type
  8.  
  9.   TLocalThread = class(TThread)
  10.   protected
  11.     procedure Execute(); override;
  12.   public
  13.     Action: String;
  14.   end;
  15.  
  16.   procedure TLocalThread.Execute();
  17.   var
  18.     i: Integer = 0;
  19.   begin
  20.     Sleep(100);
  21.  
  22.     if Action = 'trapped exception' then
  23.     begin
  24.       Writeln('trapped exception');
  25.       try
  26.         raise Exception.Create('TLocalThread trapped exception');
  27.       except
  28.         on E: Exception do
  29.         begin
  30.           Writeln(E.Message);
  31.         end;
  32.       end;
  33.     end
  34.     else if Action = 'untrapped exception' then
  35.     begin
  36.       Writeln('untrapped exception');
  37.       raise Exception.Create('TLocalThread untrapped exception');
  38.     end
  39.     else if Action = 'hang' then
  40.     begin
  41.       Writeln('hang');
  42.       while not Terminated do   //while thread not terminated
  43.       begin
  44.         Writeln('loop no ', i);
  45.         Inc(i);
  46.         Sleep(100);
  47.       end;
  48.     end
  49.     else
  50.     begin
  51.       Writeln('success');
  52.     end;
  53.   end;
  54.  
  55. var
  56.   tsuccess, ttrappedexception, tuntrappedexception, {%H-}thang: TLocalThread;
  57. begin
  58.   {%region 'success'}
  59.   Writeln('TESTING success === START');
  60.   tsuccess := TLocalThread.Create(True);
  61.   try
  62.     tsuccess.Action := ''; // success
  63.     tsuccess.Start();
  64.  
  65.     //Sleep(3000);  //?
  66.   finally
  67.     tsuccess.WaitFor;
  68.     tsuccess.Free();
  69.   end;
  70.   Writeln('TESTING success === END');
  71.   {%endregion}
  72.   {%region 'trapped exception'}
  73.   Writeln('TESTING trapped exception === START');
  74.   ttrappedexception := TLocalThread.Create(True);
  75.   try
  76.     ttrappedexception.Action := 'trapped exception';
  77.     ttrappedexception.Start();
  78.  
  79.     //Sleep(3000);  //?
  80.   finally
  81.     ttrappedexception.WaitFor;
  82.     ttrappedexception.Free();
  83.   end;
  84.   Writeln('TESTING trapped exception === END');
  85.   {%endregion}
  86.   {%region 'untrapped exception'}
  87.   Writeln('TESTING untrapped exception === START');
  88.   tuntrappedexception := TLocalThread.Create(True);
  89.   try
  90.     tuntrappedexception.Action := 'untrapped exception';
  91.     tuntrappedexception.Start();
  92.  
  93.     //Sleep(3000);  //?
  94.   finally
  95.     tuntrappedexception.WaitFor;
  96.     tuntrappedexception.Free();
  97.   end;
  98.   Writeln('TESTING untrapped exception === END');
  99.   {%endregion}
  100.   {%region 'hang'}
  101.   Writeln('TESTING hang === START');
  102.   thang := TLocalThread.Create(True);
  103.   try
  104.     thang.Action := 'hang';
  105.     thang.Start();
  106.  
  107.     Sleep(3000);
  108.   finally
  109.     thang.Terminate;  //<-- terminate thread
  110.     thang.WaitFor;
  111.     thang.Free();
  112.   end;
  113.   Writeln('TESTING hang === END');
  114.   {%endregion}
  115.   ReadLn;
  116. end.  
Best regards / Pozdrawiam
paweld

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: How would you manage this thread related problem?
« Reply #2 on: September 07, 2023, 05:24:52 pm »
use Thread.Terminate

Thanks. You modified both the part ouside the thread operation and inside the thread itself, and you suggest to use Thread.Terminate. This is fine but is another problem, that I knew already how to manage.

I need to know how (if is possible) to resolve the situation in the example of thread that I posted.
« Last Edit: September 07, 2023, 05:27:05 pm by Чебурашка »
FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 12345
  • Debugger - SynEdit - and more
    • wiki
Re: How would you manage this thread related problem?
« Reply #3 on: September 07, 2023, 06:30:44 pm »
In general your problem may be bigger than you expect.

I don't know the exact syntax, nor if there is a cross platform abstraction. But you would have to to what "kill -9" does (maybe "fpKill" on linux? / The Win API probably has something too).

But... I assume your real live example is not looping a call to sleep?
Your real live example is stuck doing "something".

And if that something could have calls to the mem-manager..., I would have to check if the mem manager acquires locks. And if it get "killed -9" then that lock may forever block any other thread from getting or freeing mem...

Depending on the code, there could be all sort of other "left overs". So in most (IMHO most)  scenarios, forcefully terminating the thread, is only good if your app is exiting too.


Well haven't tested any of that. Just from distant memory ...

Чебурашка

  • Hero Member
  • *****
  • Posts: 593
  • СЛАВА УКРАЇНІ! / Slava Ukraïni!
Re: How would you manage this thread related problem?
« Reply #4 on: September 08, 2023, 08:41:55 am »
But... I assume your real live example is not looping a call to sleep?
Your real live example is stuck doing "something".

Yes, this was just an example to simulate a situation where thread is doing something endless, and without communication with external world (for example it could be that you get a piece of compiled runnable code made by somebody else that did not foresee interaction and goes in a endless wait, a loop or a deadlock or something else weird)

And if that something could have calls to the mem-manager..., I would have to check if the mem manager acquires locks. And if it get "killed -9" then that lock may forever block any other thread from getting or freeing mem...

Depending on the code, there could be all sort of other "left overs". So in most (IMHO most)  scenarios, forcefully terminating the thread, is only good if your app is exiting too.

I understand, now I realize could be memory manager messed up, there could be interlocks, network resources lost forever. I realize that killing thread can (actually it will) leave owning process with a lost of "left overs" how you call them. Also I saw on StackOverflow the same oservations as yours.

I am now more convinced that if I want to make sure situations like this of a stuck operation, to be managed better, without leaving zombies in the process, is to externalize these operations in a separate process, so that if it gets stuck, I can kill it and all the open resources will be cleaned up by the OS and not remaining in the original process.

Thank you vm

FPC 3.2.0/Lazarus 2.0.10+dfsg-4+b2 on Debian 11.5
FPC 3.2.2/Lazarus 2.2.0 on Windows 10 Pro 21H2

 

TinyPortal © 2005-2018