TThread terminated value in constructor and Execute. lazarus / 62-General ---------------------------------------------------------------------- valerife · 2016-11-30 10:59 Hello, I am writing a simple program and i am facing an issue with the TThread class. I would like to handle the error in my create and set Terminate to true in my constructor if something wrong happen in my initialisation. However the really weird thing is this : The value of Terminated in my constructor is False, (i printed it before and after the inherited Create(False) of the TThread class) and true in my execute Here is an example of my issue : 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  {$mode objfpc}{$H+} uses    {$ifdef unix}    cthreads,    cmem,  {$endif} heaptrc, Classes, SysUtils, MyThread;var  MyThread : TMyThread;begin  try   try     MyThread := MyThread.Create;   Except     on E : Exception do        writeln(E.Message);   end;  finally    FreeAndNIl(MyThread);  end;end.  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 TMyThread = class(TThread)public      constructor Create;      destructor Destroy; override;      procedure Execute; override;                         end; constructor TMyThread.Create;begin  if (Terminated) then writeln('The value is TRUE before Inherited in Constructor'); else writeln('The value is FALSE before Inherited in Constructor');   inherited Create(False);  if (Terminated) then writeln('The value is TRUE after Inherited in Constructor'); else writeln('The value is FALSE after Inherited in Constructor');end; destructor TMyThread.Destroy;begin  inhertied Destroy;end; procedure TMythread.Excecute;begin  if (Terminated) then writeln('The value is TRUE in Execute '); else writeln('The value is FALSE in execute');end;  In console output i will have : QuoteThe value is FALSE before Inherited in Constructor The value is FALSE after Inherited in Constructor The value is TRUE in Execute Is this Normal ? Thank you very much ! ---------------------------------------------------------------------- Cyrax · 2016-11-30 12:48 It is. Inside your TThread constructor, there is no time for OS to switch execution from main thread to your thread. You need to add call to ThreadSwitch (preferably inside While not Terminated loop)  procedure after inherited Create(..) clause to achieve the result you seek. ---------------------------------------------------------------------- valerife · 2016-11-30 12:54 Hi Cyrax, Thanks you for your answer. My issue right here is the value of Terminated is True in the Execute, i can t do a While not terminated loop in the Execute. I might have missunderstand somethine in the TThread class about value of terminated ? ---------------------------------------------------------------------- User137 · 2016-11-30 13:35 Use some different boolean variable to tell that there was error maybe? Assign it in Create and check at beginning of Execute. That way you have control that it won't enter the loop at all. ---------------------------------------------------------------------- valerife · 2016-11-30 13:47 I think i will go for something like this. I thought it was cleaner to use the terminated boolean of the TThread class however it look causing more issues (if i am using it correctly). Thank you ---------------------------------------------------------------------- Remy Lebeau · 2016-11-30 21:49 Your example code is destroying the TThread object as soon as its constructor exits.  That code happens to be running before Execute() has started running.  I don't know if FreePascal's TThread destructor works the same way as Delphi's TThread destructor, but in Delphi, if TThread is still running when it is being destroyed, the destructor calls Terminate() and waits for the thread to finish running before then releasing its resources from memory.  That would certainly explain why you see Terminated is True in Execute(). ---------------------------------------------------------------------- User137 · 2016-12-01 03:21 Looking more closely i don't actually understand what's going on. Is it a Lazarus or fpc bug? He isn't calling destroy or terminate at any point, so i don't think it should behave like that. Suspended parameter true or false shouldn't affect that, it only determines if thread starts with or without Start command. But also i couldn't compile your code. There are even typos like "TMythread.Excecute;" and semicolons in wrong places of IF statements. I tried it with modifications with simple console app and so on, and all i get is sigsegv after at most 1 line printed to console. If you run a thread on console app, shouldn't you have some sort of main loop? I didn't try this as TForm based app which would actually be simpler. But then you can't use writeln(). edit: Oops, yes he is destroying with 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 finally    FreeAndNIl(MyThread); ---------------------------------------------------------------------- tetrastes · 2016-12-01 08:19 Quote from: User137 on December 01, 2016, 04:21:59 amI didn't try this as TForm based app which would actually be simpler. But then you can't use writeln(). Windows is not the only OS ---------------------------------------------------------------------- molly · 2016-12-01 13:48 Quote from: tetrastes on December 01, 2016, 09:19:40 amQuote from: User137 on December 01, 2016, 04:21:59 amI didn't try this as TForm based app which would actually be simpler. But then you can't use writeln(). Windows is not the only OS  And even it it was: Uncheck Project->Options->Config & Target->Target-Specific Options->Win32 gui application Besides that, last time i checked writeln was not thread safe. ---------------------------------------------------------------------- User137 · 2016-12-03 02:47 Linux and mac gui apps need that switch too? ---------------------------------------------------------------------- molly · 2016-12-03 03:33 Quote from: User137 on December 03, 2016, 03:47:39 amLinux and mac gui apps need that switch too? afaik, no. That is a Windows only switch. See also here. For windows applications this is required so that the lazarus application automatically assigns input and output handles to a console. If you don't uncheck that configuration option, then there will be no input and output handles assigned and that will cause an I/O error when invoking a call to read/write. afaik input and output handles are always available under Linux and MacOS. So, for Linux and Mac this should work out of the box. In case you don't have any visible output then you can use the run parameter options. In case you have that configured to automatically close your terminal on program exit, then you should add a readln just before your app terminates (which works in a similar way when using Windows). Most small test applications exits too quickly, in which case you are unable to see/read the terminal output.