Recent

Author Topic: Playing with thread, memory leaks  (Read 38385 times)

Fred vS

  • Hero Member
  • *****
  • Posts: 1675
    • miXimum is the DJ's best friend
Re: Playing with thread, memory leaks
« Reply #45 on: February 19, 2014, 01:53:37 am »
Quote
about setting the onTerminate event and do the clean up in that event?

Excellent idea  ;D

I will try that... (but is it safe to set to nil the thread by himself ?)

Quote
In theory you could define another instance variable that would be a pointer

Yep, nice too, i will try that too.

Write you later...

Many thanks.
« Last Edit: February 19, 2014, 02:02:31 am by Fred vS »
I use Lazarus 1.8.0 32/64 and FPC 3.0.3 32/64 on Linux Mint Mate 17 32/64, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: Playing with thread, memory leaks
« Reply #46 on: February 19, 2014, 02:13:06 am »
(but is it safe to set to nil the thread by himself ?)


The onTerminate event is execute inside the main thread after the execute method returned and before the thread is freed (when the FreeOnTerminate is set). It is the equivalent of the freeandnil setting the variable to nil before freeing the object.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Fred vS

  • Hero Member
  • *****
  • Posts: 1675
    • miXimum is the DJ's best friend
Re: Playing with thread, memory leaks
« Reply #47 on: February 19, 2014, 02:36:35 pm »
@ Taazz : here your excellent idea...

Hum, i have test it and i do not hear any aaaaargh and do not see smoke or fire in my computer...

But it seems so nice and simple that i do not believe it, is that code ok ?

Code: [Select]
type
 TMyGoodEndThread = class(TThread)
  protected
    ...
    procedure onTerminate;
    ...
  public
     constructor Create(CreateSuspended: boolean;
      const StackSize: SizeUInt = DefaultStackSize);
    ...
  end;

constructor TMyGoodEndThread.Create(CreateSuspended: boolean;
  const StackSize: SizeUInt);
  begin
  inherited Create(CreateSuspended, StackSize);
  FreeOnTerminate := false;   
  ...
  end;

procedure TMyGoodEndThread.onTerminate() ;
  begin
  FreeAndNil(self);
  end;
I use Lazarus 1.8.0 32/64 and FPC 3.0.3 32/64 on Linux Mint Mate 17 32/64, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: Playing with thread, memory leaks
« Reply #48 on: February 19, 2014, 03:08:07 pm »
nope that's not it. Which variable the freeandnil(self) sets to nil? What happens if there more than one variables with that thread as value?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Fred vS

  • Hero Member
  • *****
  • Posts: 1675
    • miXimum is the DJ's best friend
Re: Playing with thread, memory leaks
« Reply #49 on: February 19, 2014, 03:11:13 pm »
Quote
Which variable the freeandnil(self) sets to nil?

Hum, self is the thread himself (No/Yes) ?
I use Lazarus 1.8.0 32/64 and FPC 3.0.3 32/64 on Linux Mint Mate 17 32/64, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs

taazz

  • Hero Member
  • *****
  • Posts: 5363
Re: Playing with thread, memory leaks
« Reply #50 on: February 19, 2014, 03:15:37 pm »
you never check the thread it self for nil though you check the variables if they are nil, yes?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

Fred vS

  • Hero Member
  • *****
  • Posts: 1675
    • miXimum is the DJ's best friend
Re: Playing with thread, memory leaks
« Reply #51 on: February 19, 2014, 03:29:53 pm »
Ok, i will try to explain a other way (using Taazz idea).

This one use array, is it better ?

Code: [Select]
type
 TMyGoodEndThread = class(TThread)
  protected
    ...
    procedure onTerminate; =====> here added
    ...
  public
     Index: cardinal;  ====> here added
     constructor Create(CreateSuspended: boolean;
      const StackSize: SizeUInt = DefaultStackSize);
    ...
  end;

type
TArrayGoodEndThread = array of TMyGoodEndThread;

var
MyArrayGoodThread : TArrayGoodEndThread ;


constructor TMyGoodEndThread.Create(CreateSuspended: boolean;
  const StackSize: SizeUInt);
  begin
  inherited Create(CreateSuspended, StackSize);
  FreeOnTerminate := false;   
  ...
  end;

procedure CreateArrayGoodEndThread(indexarray :cardinal);
begin
setlength(MyArrayGoodThread, indexarray);
MyArrayGoodThread[indexarray] := TMyGoodEndThread.Create(true);
MyArrayGoodThread[indexarray].index := indexarray; =====> here added
end;

procedure TMyGoodEndThread.onTerminate() ;
  begin
  FreeAndNil(MyArrayGoodThread[index]);
  end;
« Last Edit: February 19, 2014, 03:40:38 pm by Fred vS »
I use Lazarus 1.8.0 32/64 and FPC 3.0.3 32/64 on Linux Mint Mate 17 32/64, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Playing with thread, memory leaks
« Reply #52 on: February 19, 2014, 04:55:29 pm »
Array is fine, but there is at least 1 point you need to note:
1) Can you delete indexes from between? If you move indexes backwards (to fill the empty gap of deleted thread), you have to update the index value within each thread that are moved too.

2) You allocate 1 too few  ;D  Should be:
Code: [Select]
setlength(MyArrayGoodThread, indexarray+1);

Fred vS

  • Hero Member
  • *****
  • Posts: 1675
    • miXimum is the DJ's best friend
Re: Playing with thread, memory leaks
« Reply #53 on: February 19, 2014, 09:34:08 pm »
Quote
2) You allocate 1 too few  ;D  Should be:
Code: [Select]

setlength(MyArrayGoodThread, indexarray+1);

Repor

No : that is the right code :

Code: [Select]
if indexarray+1 > length(MyArrayGoodThread) then setlength(MyArrayGoodThread, indexarray+1);  ;D ;D

Otherwise, you will have trouble with already created thread.

But, good, you are attentive..  :-*

Quote
1) Can you delete indexes from between? If you move indexes backwards (to fill the empty gap of deleted thread), you have to update the index value within each thread that are moved too.

Hum, i decide to not to play with moving index.
Too much problems, with few advantages...
If the thread was freed and assigned to nil, it is not very heavy inside the array...
And if the new length of array contain unassigned thread, it is not a big problem because nothing was created after setlength().
For that, i use a "twins" array of integer who vary in length with the thread array.
And when a thread is created => assign 1 to that twins{x].
So i can check in the thread array if thread{x] was already created.


PS : @ Taazz : part of you is inside uos now... :-X
« Last Edit: February 19, 2014, 10:14:40 pm by Fred vS »
I use Lazarus 1.8.0 32/64 and FPC 3.0.3 32/64 on Linux Mint Mate 17 32/64, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64 and Mac OS X Snow Leopard 32.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt, Carbon.

https://github.com/fredvs