Recent

Author Topic: free stringlist in Tthread  (Read 15634 times)

victor11109

  • New Member
  • *
  • Posts: 19
free stringlist in Tthread
« on: April 02, 2024, 07:53:21 pm »
i have multithread app like these code . question is why my mainList not get freed . but if load file in thread itself not in main thread . then main list get freed in finally block .

Code: Pascal  [Select][+][-]
  1.  
  2. program project1;
  3.  
  4. uses
  5.   Classes,
  6.   SysUtils;
  7.  
  8. type
  9.  
  10.   { TmyThread }
  11.  
  12.   TmyThread = class(TThread)
  13.     mainList: TStringList;
  14.     procedure LoadMain;
  15.   public
  16.     constructor Create;
  17.     procedure Execute; override;
  18.   end;
  19.  
  20.   { TmyThread }
  21.  
  22.   procedure TmyThread.LoadMain;
  23.   begin
  24.     mainList.LoadFromFile('myfile.txt');
  25.   end;
  26.  
  27.   constructor TmyThread.Create;
  28.   begin
  29.     inherited Create(False);
  30.     FreeOnTerminate := True;
  31.   end;
  32.  
  33.   procedure TmyThread.Execute;
  34.   begin
  35.     mainList := TStringList.Create;
  36.     try
  37.       Synchronize(@LoadMain);
  38.       Sleep(5000);
  39.     finally
  40.       mainList.Free;
  41.     end;
  42.  
  43.   end;
  44.  
  45. var
  46.   MTH: TmyThread;
  47. begin
  48.   MTH := TmyThread.Create;
  49.   while True do
  50.   begin
  51.     CheckSynchronize(0);
  52.     Sleep(1000);
  53.   end;
  54. end.
  55.  
  56.  

cdbc

  • Hero Member
  • *****
  • Posts: 1085
    • http://www.cdbc.dk
Re: free stringlist in Tthread
« Reply #1 on: April 02, 2024, 08:09:29 pm »
Hi
Sorry mate, but what are you trying to do?!?!?
As threading-code goes, your code is all possible kinds of wrong  %)
Creating the list in thread and loading it in the main-thread via synchronize, totally defeats the purpose of a thread....
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

victor11109

  • New Member
  • *
  • Posts: 19
Re: free stringlist in Tthread
« Reply #2 on: April 02, 2024, 08:28:42 pm »
assume myfile.txt is using in main thread  in some kind of loop and want to load that file in other thread for processing content of file so im try just load file in main thread to be safe for accesing myfile.txt file . then continue and process content of file and free the list

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9881
  • Debugger - SynEdit - and more
    • wiki
Re: free stringlist in Tthread
« Reply #3 on: April 02, 2024, 08:50:02 pm »
i have multithread app like these code . question is why my mainList not get freed . but if load file in thread itself not in main thread . then main list get freed in finally block .

I run your code as it is. With heaptrc.

Only difference, I made the endless loop exit after 20 secs.

heaptrc said no mem leaks. So the list got freed.

How did you check if it got freed?

victor11109

  • New Member
  • *
  • Posts: 19
Re: free stringlist in Tthread
« Reply #4 on: April 02, 2024, 11:20:08 pm »
i have multithread app like these code . question is why my mainList not get freed . but if load file in thread itself not in main thread . then main list get freed in finally block .

I run your code as it is. With heaptrc.

Only difference, I made the endless loop exit after 20 secs.

heaptrc said no mem leaks. So the list got freed.

How did you check if it got freed?

thanks . actualy i try to acces list member after free but it seems list be freed . but . i load a big file eg : 300mb and saw in windows taskmanager that after list be free . memory still have size of that file . there was 2 way that memory get freed in task manager :
1 - when load file inside thread insted of synchronize in main thread
2 - when load file to list in main thread and also free that list with sychronize in main thread
these 2 code below free memory in windows task manager :

Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses
  4.   Classes,
  5.   SysUtils;
  6.  
  7. type
  8.  
  9.   { TmyThread }
  10.  
  11.   TmyThread = class(TThread)
  12.     mainList: TStringList;
  13.   public
  14.     constructor Create;
  15.     procedure Execute; override;
  16.   end;
  17.  
  18.   { TmyThread }
  19.  
  20.  
  21.   constructor TmyThread.Create;
  22.   begin
  23.     inherited Create(False);
  24.     FreeOnTerminate := True;
  25.   end;
  26.  
  27.   procedure TmyThread.Execute;
  28.   begin
  29.     mainList := TStringList.Create;
  30.     try
  31.       mainList.LoadFromFile('myfile.txt');
  32.       Sleep(5000);
  33.     finally
  34.       mainList.Free;
  35.     end;
  36.  
  37.   end;
  38.  
  39. var
  40.   MTH: TmyThread;
  41. begin
  42.   MTH := TmyThread.Create;
  43.   while True do
  44.   begin
  45.     CheckSynchronize(0);
  46.     Sleep(1000);
  47.   end;
  48. end.
  49.  


Code: Pascal  [Select][+][-]
  1. program project1;
  2.  
  3. uses
  4.   Classes,
  5.   SysUtils;
  6.  
  7. type
  8.  
  9.   { TmyThread }
  10.  
  11.   TmyThread = class(TThread)
  12.     mainList: TStringList;
  13.     procedure LoadMain;
  14.     procedure FrreList;
  15.   public
  16.     constructor Create;
  17.     procedure Execute; override;
  18.   end;
  19.  
  20.   { TmyThread }
  21.  
  22.   procedure TmyThread.LoadMain;
  23.   begin
  24.     mainList.LoadFromFile('myfile.txt');
  25.   end;
  26.  
  27.   procedure TmyThread.FrreList;
  28.   begin
  29.     mainList.Free;
  30.   end;
  31.  
  32.   constructor TmyThread.Create;
  33.   begin
  34.     inherited Create(False);
  35.     FreeOnTerminate := True;
  36.   end;
  37.  
  38.   procedure TmyThread.Execute;
  39.   begin
  40.     mainList := TStringList.Create;
  41.     try
  42.       Synchronize(@LoadMain);
  43.       Sleep(5000);
  44.     finally
  45.       Synchronize(@FrreList);
  46.     end;
  47.  
  48.   end;
  49.  
  50. var
  51.   MTH: TmyThread;
  52. begin
  53.   MTH := TmyThread.Create;
  54.   while True do
  55.   begin
  56.     CheckSynchronize(0);
  57.     Sleep(1000);
  58.   end;
  59. end.
  60.  

Thaddy

  • Hero Member
  • *****
  • Posts: 14376
  • Sensorship about opinions does not belong here.
Re: free stringlist in Tthread
« Reply #5 on: April 03, 2024, 08:17:31 am »
Benny put you on the right track. Synchronise and load defeats the purpose of the thread. If you want to load a big file in the background setup a criticalsection for the list and make the list global. Then the thread has a purpose...
I think that is actually more in line with what you mean to do. Loading from a thread in synchronize is executed in the main thread... So useless. Very common misunderstanding, though. We have to explain that many times a year. (and on Delphi forums, the same...)

There seems to be a bad Omen on understanding synchronize.
« Last Edit: April 03, 2024, 10:08:51 am by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

cdbc

  • Hero Member
  • *****
  • Posts: 1085
    • http://www.cdbc.dk
Re: free stringlist in Tthread
« Reply #6 on: April 03, 2024, 10:41:44 am »
Hi
Here's how you could do it:
Code: Pascal  [Select][+][-]
  1.  
  2. program project1;
  3. {$mode objfpc}{$H+} // object-pascal dialect & long strings ON
  4. uses
  5.   {$ifdef unix}cthreads,{$endif}
  6.   Classes,
  7.   SysUtils;
  8.  
  9. var
  10.   mainList: TStringList = nil;
  11.   threadloaded: longint = 0;
  12.  
  13. Procedure LoadMain(AData : Pointer);
  14. begin
  15.   TStringList(AData).LoadFromFile('myfile.txt');
  16.   sleep(5000); { just to have something to wait for, machine too dang quick }
  17.   InterlockedIncrement(threadloaded);
  18. end;
  19.  
  20. begin
  21.   mainList := TStringList.Create;
  22.   try
  23.     writeln('(i) Loading textfile...');
  24.     { now use a builtin feature of TThread to load our list }
  25.     TThread.ExecuteInThread(@LoadMain,mainList);
  26.     write('(?) progress: ');
  27.     repeat { do not touch list in loop! }
  28.       write('#');
  29.       sleep(250);
  30.     until threadloaded > 0;
  31.     writeln;
  32.     Writeln('(!) Done. Number of lines in text: ',mainList.Count);
  33.   finally
  34.     mainList.Free;
  35.   end;
  36. end.
  37.  
  38.  
DO NOT touch the list in the 'repeat until' loop, because I've made this one without protection of a critical section!!!
Else have fun  8-)
Regards Benny
« Last Edit: April 03, 2024, 10:43:34 am by cdbc »
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 14376
  • Sensorship about opinions does not belong here.
Re: free stringlist in Tthread
« Reply #7 on: April 03, 2024, 10:45:08 am »
That one is a bit naughty, Benny. You and I can handle that, but a critical section protects the programmer as well... :-X
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

cdbc

  • Hero Member
  • *****
  • Posts: 1085
    • http://www.cdbc.dk
Re: free stringlist in Tthread
« Reply #8 on: April 03, 2024, 10:59:30 am »
Hi
Oooookay Thaddy, thought I could get away with it.... 8-)
This one's better, thanks to the *Handywork* of Sara/Sven:
Code: Pascal  [Select][+][-]
  1.  
  2. program project1;
  3. {$mode objfpc}{$H+} // object-pascal dialect & long strings ON
  4. uses
  5.   {$ifdef unix}cthreads,{$endif}
  6.   Classes,
  7.   SysUtils;
  8.  
  9. var
  10.   mainList: TStringList = nil;
  11.   threadloaded: longint = 0;
  12.   lock: IReadWriteSync = nil;
  13.  
  14. Procedure LoadMain(AData : Pointer);
  15. begin
  16.   { protect from interference while loading }
  17.   if lock.BeginWrite then try
  18.     TStringList(AData).LoadFromFile('myfile.txt');
  19.     sleep(5000);
  20.   finally lock.EndWrite; end;
  21.   InterlockedIncrement(threadloaded);
  22. end;
  23.  
  24. begin
  25.   lock:= TSimpleRWSync.Create; { service of the rtl, COM object }
  26.   mainList := TStringList.Create;
  27.   try
  28.     writeln('(i) Loading textfile...');
  29.     { now use a builtin feature of TThread to load our list }
  30.     TThread.ExecuteInThread(@LoadMain,mainList);
  31.     write('(?) progress: ');
  32.     repeat
  33.       write('#');
  34.       sleep(250);
  35.     until threadloaded > 0;
  36.     writeln;
  37.     if lock.BeginWrite then try
  38.       Writeln('(!) Done. Number of lines in text: ',mainList.Count);
  39.     finally lock.EndWrite; end;
  40.   finally
  41.     mainList.Free;
  42.   end;
  43. end.
  44.  
  45.  
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Thaddy

  • Hero Member
  • *****
  • Posts: 14376
  • Sensorship about opinions does not belong here.
Re: free stringlist in Tthread
« Reply #9 on: April 03, 2024, 11:33:05 am »
Well done.. ;) ;) ;)
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

victor11109

  • New Member
  • *
  • Posts: 19
Re: free stringlist in Tthread
« Reply #10 on: April 03, 2024, 04:06:32 pm »
Benny put you on the right track. Synchronise and load defeats the purpose of the thread. If you want to load a big file in the background setup a criticalsection for the list and make the list global. Then the thread has a purpose...
I think that is actually more in line with what you mean to do. Loading from a thread in synchronize is executed in the main thread... So useless. Very common misunderstanding, though. We have to explain that many times a year. (and on Delphi forums, the same...)

There seems to be a bad Omen on understanding synchronize.

first of all thanks to beny code examples . learn something more  :D
 but i think its my fault to send just small part of code and you guys think its bad to load file in main thread even if its bad idea program is a little complex and dont want to change whole code to use mutex . but as you must know its important to access files in main thread .

any way - about my problem some guy suggest to use cmem and its worked . so is a bug in pascal memory manager or its concept that i miss to read or learn ? ::)

cdbc

  • Hero Member
  • *****
  • Posts: 1085
    • http://www.cdbc.dk
Re: free stringlist in Tthread
« Reply #11 on: April 03, 2024, 05:41:44 pm »
Hi
Quote
but as you must know its important to access files in main thread .
Nahh, Just protect access, should be enough  :P
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

 

TinyPortal © 2005-2018