[SOLVED] Passing a variable exclusive to a thread lazarus / 21-General ---------------------------------------------------------------------- torbente · 2021-03-30 23:40 Using lazarus 2.0.10 on win 8.1 This is pseudo code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TThreadOne = class(TThread)    procedure Execute; override;  end; MySpecialVariable : int64; MyThreads: array [1..10] of TThreadOne;  For counter 1 to 10 do   begin   If Assigned(MyThreads[counter]) then MyThreads[counter].terminate;   delay(10);   MyThreads[counter] := TThreadOne.Create(true);   MyThreads[counter].FreeOnTerminate:=true;   MyThreads[counter].Start;    end procedure TThreadOne.Execute;    BeginMySpecialvariable {do many things with this variable}End My question: How i could pass a different MySpecialvariable value to each thread? Thanks. ---------------------------------------------------------------------- engkin · 2021-03-30 23:52 Depends on what you are tring to do, use Threadvar, or have similar array for that variable, one for each thread and give the thread its index in that array. As a side note, this line is not safe if you have your threads started with FreeOnTerminate is True: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    If Assigned(MyThreads[counter]) then MyThreads[counter].terminate; and the thead will not end instantly after this call. ---------------------------------------------------------------------- torbente · 2021-03-31 01:08 Quote from: engkin on March 31, 2021, 01:52:38 amDepends on what you are tring to do, use Threadvar, or have similar array for that variable, one for each thread and give the thread its index in that array. As a side note, this line is not safe if you have your threads started with FreeOnTerminate is True: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i    If Assigned(MyThreads[counter]) then MyThreads[counter].terminate; and the thead will not end instantly after this call. AFAIK, threadvar always assign the same value to all threads and then it becomes a thread-local var. I want that each thread have a different value from its beggining. Or how i could detect, inside the thread, what index of the thread array it is? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i If Assigned(MyThreads[counter]) then    try   MyThreads[counter].terminate;   finally   end; It is safe now? ---------------------------------------------------------------------- engkin · 2021-03-31 02:58 No, not safe. As for the variable, add it (the index)  to the thread class TThreadOne ---------------------------------------------------------------------- PascalDragon · 2021-03-31 06:53 Quote from: torbente on March 31, 2021, 03:08:43 amIt is safe now? No. General rule is: if FreeOnTerminate is set to True do not access the thread instance from outside anymore. The only exception is if you for sure know that the thread is running a loop and it will only terminate if you trigger some action (e.g. calling TThread.Terminate). Quote from: torbente on March 31, 2021, 03:08:43 amAFAIK, threadvar always assign the same value to all threads and then it becomes a thread-local var. I want that each thread have a different value from its beggining. Or how i could detect, inside the thread, what index of the thread array it is? If you want each thread to have a different value, why don't you simply pass it in as part of the constructor? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TThreadOne = class(TThread)  private    fMySpecialVariable: Int64;  protected    procedure Execute; override;  public    constructor Create(aMySpecialVariable: Int64);  end; constructor TThreadOne.Create(aMySpecialVariable: Int64);begin  inherited Create(True);  fMySpecialVariable := aMySpecialVariable;end; ---------------------------------------------------------------------- torbente · 2021-03-31 12:26 QuoteQuote from: torbente on Today at 03:08:43 am It is safe now? No. General rule is: if FreeOnTerminate is set to True do not access the thread instance from outside anymore. The only exception is if you for sure know that the thread is running a loop and it will only terminate if you trigger some action (e.g. calling TThread.Terminate). Ok i removed it. Since threads are a loop (repeat... until finishthread= true) i just added this to verify that all threads are terminated before creating it again: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i finishthread := true;Delay(100);finishthread := false; For the variable, i will try using counter as a global variable so each thread can get its value. Something like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i TThreadOne = class(TThread)    procedure Execute; override;  end; {Global variables} MySpecialVariable : int64;TCounter : integer;StropThread : boolean; MyThreads: array [1..10] of TThreadOne; Procedure LaunchThreads();begin StropThread := true;delay(100)StropThread := false;For TCounter := 1 to 10 do   begin   MyThreads[TCounter] := TThreadOne.Create(true);   MyThreads[TCounter].FreeOnTerminate:=true;   MyThreads[TCounter].Start;   Delay(10);   endend; procedure TThreadOne.Execute;   var  MySpecialvariable : integer; BeginMySpecialvariable := TCounter;Repeat{use of MySpecialvariable}until StropThread;End  This should work, but threads are so complex that i will try it first. ---------------------------------------------------------------------- ASerge · 2021-03-31 14:23 Quote from: torbente on March 31, 2021, 02:26:52 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i //...Procedure LaunchThreads();begin StropThread := true;delay(100)StropThread := false;For TCounter := 1 to 10 do   begin   MyThreads[TCounter] := TThreadOne.Create(true);   MyThreads[TCounter].FreeOnTerminate:=true;   MyThreads[TCounter].Start;   Delay(10);   endend; procedure TThreadOne.Execute;   var  MySpecialvariable : integer; BeginMySpecialvariable := TCounter;Repeat{use of MySpecialvariable}until StropThread;End  This should work, but threads are so complex that i will try it first. In this case, all threads can get the same value of MySpecialVariable. In addition, since the threads itself are released, why do you need an array of references to it's? Example: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$APPTYPE CONSOLE}{$MODE OBJFPC} uses Classes; type  TThreadOne = class(TThread)  protected    procedure Execute; override;  public    constructor Create;  end; var  GActiveThreadsCount: Integer = 0;  GStopWhenNotZero: Integer = 0; constructor TThreadOne.Create;begin  inherited Create(False);  FreeOnTerminate := True;end; procedure TThreadOne.Execute;var  MySpecialVariable: Integer;begin  MySpecialVariable := InterlockedIncrement(GActiveThreadsCount);  try  while GStopWhenNotZero = 0 do    begin      {use of MySpecialVariable}      Writeln('Thread ID=', ThreadID, ', MySpecialvariable=', MySpecialVariable);      MySpecialVariable := MySpecialVariable * 10;      Sleep(250);    end;  finally    InterlockedDecrement(GActiveThreadsCount);  end;end; procedure TerminateThreads;begin  Writeln('TerminateThreads');  InterlockedIncrement(GStopWhenNotZero);  while GActiveThreadsCount > 0 do    TThread.Sleep(100);end; procedure LaunchThreads;var  i: SizeInt;begin  TerminateThreads;  Writeln('LaunchThreads');  GStopWhenNotZero := 0;  for i := 1 to 3 do    TThreadOne.Create;end; begin  LaunchThreads;  TThread.Sleep(1000);  TerminateThreads;  Readln;end. ---------------------------------------------------------------------- torbente · 2021-04-01 20:19 I have to said that it worked perfectly; leaving a small delay makes that each thread gets a different value from TCounter. This, of course, is a workoarund only, but could help others to implement an easy solution for this situations. I believe that an easy way to do this should be something like.. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MyThreads[TCounter] := TThreadOne.Create(true);MyThreads[TCounter].Fre eOnTerminate:=true;MyThreads[TCounter].SetInternalVariable(MySpecialva riable,1); //or something like thatMyThreads[TCounter].Start; ---------------------------------------------------------------------- Gustavo 'Gus' Carreno · 2021-04-21 20:57 Hey Torbente, If you define your TThreadOne as so: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TThreadOne = class(TThread)  private    FMySpecialVariable: Int64;  protected    procedure Execute; override;  public    property MySpecialVariable: Int64      read FMySpecialValiable      write FMySpecialVariable;  end; You can then do: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i For TCounter := 1 to 10 do   begin   MyThreads[TCounter] := TThreadOne.Create(true);   MyThreads[TCounter].FreeOnTerminate:=true;   MyThreads[TCounter].MySpecialVariable:= { Whatever you wanna put here };   MyThreads[TCounter].Start;   Delay(10);   endend; And that's for a Read/Write property. If you want a Read Only, then: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i interfacetype  TThreadOne = class(TThread)  private    FMySpecialVariable: Int64;  protected    procedure Execute; override;  public    constructor Create(CreateSuspended: Boolean; MySpecialVariable: Int64);     property MySpecialVariable: Int64 { This can be committed if there is no use for it outside the thread }    read FMySpecialValiable;  end;implementationconstructor TThreadOne.CreateSuspended: Boolean; MySpecialVariable: Int64);begin  inherited Create(CreateSuspended);  FMySpecialVariable:= MySpecialVariable;end; And then: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i For TCounter := 1 to 10 do   begin   MyThreads[TCounter] := TThreadOne.Create(true, { The value of MySpecialVariable });   MyThreads[TCounter].FreeOnTerminate:=true;   MyThreads[TCounter].Start;   Delay(10);   endend;