Lazarus

Free Pascal => Beginners => Topic started by: incendio on June 15, 2019, 08:33:48 am

Title: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 15, 2019, 08:33:48 am
Hi guys,

I have thread declaration in mainunit.pas
Code: Pascal  [Select][+][-]
  1. type
  2.  
  3.   { TMyThread }
  4.  
  5.   TMyThread = class(TThread)
  6.   private
  7.     fStatusText: string;
  8.     procedure ShowStatus;
  9.   protected
  10.     procedure Execute; override;
  11.   public
  12.     constructor Create(CreateSuspended: boolean);
  13.   end;
  14.  
  15.   { D3 }
  16.   TD3GetDtThr = class(TThread)
  17.   protected
  18.     procedure Execute; override;
  19.   public
  20.     constructor Create(CreateSuspended: boolean);
  21.   end;
  22.  
  23.   TMainFrm = class(TForm)
  24.     btnStart: TButton;
  25.     Label1: TLabel;
  26.     Label2: TLabel;
  27.     Label3: TLabel;
  28.     Label4: TLabel;
  29.     Label5: TLabel;
  30.     Label6: TLabel;
  31.     Label7: TLabel;
  32.     Label8: TLabel;
  33.     lblThr: TLabel;
  34.     lblStTm: TLabel;
  35.     lblTmDf: TLabel;
  36.     P0: TProgressBar;
  37.     P1: TProgressBar;
  38.     P2: TProgressBar;
  39.     P3: TProgressBar;
  40.     P4: TProgressBar;
  41.     P5: TProgressBar;
  42.     procedure btnStartClick(Sender: TObject);
  43.     procedure FormCreate(Sender: TObject);
  44.     procedure ThreadDone(Sender: TObject);
  45.     procedure Go();
  46.   private
  47.   public
  48.   end;
  49.  
  50. procedure TMainFrm.ThreadDone(Sender: TObject);
  51. begin
  52.   ThreadsRunning := ThreadsRunning-1;
  53.   P0.StepIt;
  54.  
  55.   if (ThreadsRunning > 0) then
  56.   begin
  57.     lblThr.Caption:= IntToStr(ThreadsRunning);
  58.     lblTmDf.Caption := IntToStr(SecondsBetween(StartTime,Now));
  59.   end;
  60. end;
  61.  

Procedure for TD3GetDtThr
Code: Pascal  [Select][+][-]
  1. constructor TD3GetDtThr.Create(CreateSuspended: boolean);
  2. begin
  3.   FreeOnTerminate := True;
  4.   inherited Create(CreateSuspended);
  5. end;
  6.  
  7. procedure TD3GetDtThr.Execute;
  8. begin
  9. end;
  10.  

Code to start the thread
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := Dt5.Create(False);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7.   Dt5.Start;
  8. end;
  9.  

When procedure Go() called, got the error
class 'external : SIGSEGV'
in file mainunit.pas line 197
FreeOnTerminate := True;

That error point to constructor TD3GetDtThr.Create

What is wrong with the codes?

Thanks in advance.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 15, 2019, 08:46:29 am
You create the thread with createsuspended false.
That means the thread already runs.
After that you call start on a running thread!

I usually do not recommend it, but in this case you can use CreateSuspended= true, then call start when everything is set up.
Report back if that doesn't solve the issue: this was eyes only and I did not test.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 15, 2019, 09:05:16 am
I have tried this code
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := Dt5.Create(false);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7.   //Dt5.Start;
  8. end;
  9.  

and this code
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := Dt5.Create(True);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7.   Dt5.Start;
  8. end;
  9.  

Still got the same error.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: SymbolicFrank on June 15, 2019, 09:22:15 am
Can you post a project that shows the error?
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 15, 2019, 09:29:22 am
Can you post a project that shows the error?
What do you mean?

The error point to this procedure, on the line FreeOnTerminate := True;
Code: Pascal  [Select][+][-]
  1. constructor TD3GetDtThr.Create(CreateSuspended: boolean);
  2. begin
  3.   FreeOnTerminate := True;
  4.   inherited Create(CreateSuspended);
  5. end;        
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 15, 2019, 09:40:13 am
Found the problem!

The error caused by error in thread declaration.

This is the error declaration
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := Dt5.Create(false);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7. end;            

It should be like this
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := TD3GetDtThr.Create(false);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7. end;            

It can compile cause Lazarus doesn't point to that declaration.

Thanks anyway for your help.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 15, 2019, 10:17:39 am
There is still a basic error:
You should call the inherited first in the constructor, then the housekeeping. The inherited might reset things.....
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 15, 2019, 12:42:56 pm
I copied Lazarus example that called inherited last.

I will change though as your suggestion. Thanks.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: ASerge on June 15, 2019, 09:51:13 pm
This is the error declaration
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := TD3GetDtThr.Create(false);
  6.   Dt5.OnTerminate:= @ThreadDone;
  7. end;
You found the obvious error, but in vain ignored what Thaddy said. In code above the sixth line of code can be executed after the thread is finished and freed. Make all settings in the constructor or call with Suspended = True.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 16, 2019, 01:51:32 pm
You found the obvious error, but in vain ignored what Thaddy said. In code above the sixth line of code can be executed after the thread is finished and freed. Make all settings in the constructor or call with Suspended = True.

I don't use constructor anymore.

Here are the codes :
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt1 : TLocGetDtThr1;
  4.   Dt6 : TLocGetDtThr2;
  5.   Dt2 : TDptGetDtThr;
  6.   Dt3 : TRtlGetDtThr;
  7.   Dt4 : TAssGetDtThr1;
  8.   Dt7 : TAssGetDtThr2;
  9.   Dt5 : TD3GetDtThr;
  10. begin
  11.   Dt1                := TLocGetDtThr1.Create( False);
  12.   Dt1.FreeOnTerminate:= True;
  13.   Dt1.OnTerminate    := @ThreadDone;
  14.  
  15.   Dt6                := TLocGetDtThr2.Create( False);
  16.   Dt6.FreeOnTerminate:= True;
  17.   Dt6.OnTerminate    := @ThreadDone;
  18.  
  19.   Dt2                := TDptGetDtThr.Create(False);
  20.   Dt2.FreeOnTerminate:= True;
  21.   Dt2.OnTerminate    := @ThreadDone;
  22.  
  23.   Dt3                := TRtlGetDtThr.Create(False);
  24.   Dt3.FreeOnTerminate:= True;
  25.   Dt3.OnTerminate    := @ThreadDone;
  26.  
  27.   Dt4                := TAssGetDtThr1.Create(False);
  28.   Dt4.FreeOnTerminate:= True;
  29.   Dt4.OnTerminate    := @ThreadDone;
  30.  
  31.   Dt7                := TAssGetDtThr2.Create(False);
  32.   Dt7.FreeOnTerminate:= True;
  33.   Dt7.OnTerminate    := @ThreadDone;
  34.  
  35.   Dt5                := TD3GetDtThr.Create(False);
  36.   Dt5.FreeOnTerminate:= True;
  37.   Dt5.OnTerminate    := @ThreadDone;
  38. end;
  39.  
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: ASerge on June 17, 2019, 03:49:13 am
I don't use constructor anymore.
All the more need "Suspended = True".
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 08:09:45 am
I don't use constructor anymore.
All the more need "Suspended = True".
I would still use the constructor, but like so:
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := TD3GetDtThr.Create(false);
  6. end;    
  7.  
  8. constructor TD3GetDtThr.Create(CreateSuspended: boolean); // Set to true or false, see below
  9. begin
  10.   inherited Create(true); // Always call inherited first. MUST be true, so you can also set it directly to true here
  11.   FreeOnTerminate := True;
  12.   Dt5.OnTerminate:= @ThreadDone; // Can do that here
  13.  If CreateSuspended = false then Start;  // Now it starts  immediately after setup if CreateSuspended = false and manually when true
  14. end;  
     
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 17, 2019, 08:15:10 am
I don't use constructor anymore.
All the more need "Suspended = True".
I would still use the constructor, but like so:

What is the benefit using constructor instead of not using it?
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 08:43:06 am
As you can see, all house keeping / setup is done on a central place in the constructor.
You can subsequently run the thread with suspended = false as you intended, because of the way I set up the thread.
It is rather obvious: It prevents you from modifying a running thread! Which is essential.
If you look at my code you see I solved both your mistakes:
1. Inherited first, then the properties
2. You can now create the thread with suspended = false in a safe manner, because during the setup the thread is not started yet. and it still starts immediately after create.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 17, 2019, 01:18:37 pm
Ok, thanks for your help, I will change the codes.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 17, 2019, 01:42:34 pm
I would still use the constructor, but like so:
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := TD3GetDtThr.Create(false);
  6. end;    
  7.  
  8. constructor TD3GetDtThr.Create(CreateSuspended: boolean); // Set to true or false, see below
  9. begin
  10.   inherited Create(true); // Always call inherited first. MUST be true, so you can also set it directly to true here
  11.   FreeOnTerminate := True;
  12.   Dt5.OnTerminate:= @ThreadDone; // Can do that here
  13.  If CreateSuspended = false then Start;  // Now it starts  immediately after setup if CreateSuspended = false and manually when true
  14. end;  
     
How would you reach a local variable Dt5 in TMainFrm.Go() from TD3GetDtThr.Create() ?????????????

Anyway, I wouldn't use any hard variable inside TD3GetDtThr because you can't use TD3GetDtThr anywhere else then.

If you really want to, you could override the TD3GetDtThr.Create and pass the ThreadDone as parameter.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 01:47:25 pm
Yes, I overlooked that. That's the third mistake in the code.
It should be a form variable or better a global.
Local thread variables are not a good idea.... ;D :( They are not longer accessible after the method exits and can lead to side effects even if the thread is still running.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 17, 2019, 01:48:56 pm
B.T.W. does inherited Create(false); really start the thread right away?
According to me it waits until the construction is finished.
So you can just do inherited Create(CreateSuspended); in that constructor and remove the Start at the end.
Execute won't run before the constructor is finished, does it?

(bug in the wiki?)

Code: Pascal  [Select][+][-]
  1. constructor TD3GetDtThr.Create(CreateSuspended: boolean); // Set to true or false, see below
  2. begin
  3.   inherited Create(CreateSuspended); // no need to start it paused, is there??
  4.   FreeOnTerminate := True;
  5.  
  6.   // do some other initializing...
  7.  
  8.   // If CreateSuspended = false then Start;when true
  9. end;  
     
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 01:52:59 pm
I consider that implementation detail, but inherited create(false) will finish so the thread should be running at that point.
In Delphi we had all kinds of problems because of that. I am not sure about the details for FPC.
My approach is at least a safe approach.
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 17, 2019, 02:06:37 pm
I would still use the constructor, but like so:
Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.Go();
  2. var
  3.   Dt5 : TD3GetDtThr;
  4. begin
  5.   Dt5 := TD3GetDtThr.Create(false);
  6. end;    
  7.  
  8. constructor TD3GetDtThr.Create(CreateSuspended: boolean); // Set to true or false, see below
  9. begin
  10.   inherited Create(true); // Always call inherited first. MUST be true, so you can also set it directly to true here
  11.   FreeOnTerminate := True;
  12.   Dt5.OnTerminate:= @ThreadDone; // Can do that here
  13.  If CreateSuspended = false then Start;  // Now it starts  immediately after setup if CreateSuspended = false and manually when true
  14. end;  
     
How would you reach a local variable Dt5 in TMainFrm.Go() from TD3GetDtThr.Create() ?????????????

Anyway, I wouldn't use any hard variable inside TD3GetDtThr because you can't use TD3GetDtThr anywhere else then.

If you really want to, you could override the TD3GetDtThr.Create and pass the ThreadDone as parameter.
You were right. Dt5 variable won't recognised on thread create procedure.

So, back to old code then, without constructor.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 17, 2019, 02:13:16 pm
I consider that implementation detail, but inherited create(false) will finish so the thread should be running at that point.
In Delphi we had all kinds of problems because of that. I am not sure about the details for FPC.
My approach is at least a safe approach.
The thread might be created and running but I don't think the Execute will run before the constructor is finished.
But you are correct, that could be en implementation detail which might not be exactly be implemented as I described so your approach will be indeed the safest course.

So, back to old code then, without constructor.
So, do something like this:

Code: Pascal  [Select][+][-]
  1. type
  2.   TD3GetDtThr = class(TThread)
  3.   protected
  4.     procedure Execute; override;
  5.   public
  6.     constructor Create(CreateSuspended: boolean; AThreadDone: TNotifyEvent); reintroduce; overload;
  7.   end;
  8.  
  9. constructor TD3GetDtThr.Create(CreateSuspended: boolean; AThreadDone: TNotifyEvent);
  10. begin
  11.   inherited Create(true);
  12.   FreeOnTerminate := true;
  13.   OnTerminate := AThreadDone; // prefix with @ if in Delphi mode
  14.   if not CreateSuspended then Start;
  15. end;

(Not exactly sure if the reintroduce; overload; are absolutely required.)
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 02:58:46 pm
Neat solution, any code can be improved upon at some time. The reintroduce is indeed not necessary. Maybe const ThreadDone, though
Title: Re: Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 17, 2019, 03:02:34 pm
So, back to old code then, without constructor.
In that case remember:
- CreateSuspended should be TRUE!
- First the setup, then call start
- Order is important.

By now this advice has been given not just by me, but by three "Old Hands" and we more or less agree.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: ASerge on June 17, 2019, 09:42:26 pm
But you are correct, that could be en implementation detail which might not be exactly be implemented as I described so your approach will be indeed the safest course.
In Delphi documented that the thread starts in the AfterСonstructor. http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.Create (http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.Create), http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.AfterConstruction (http://docwiki.embarcadero.com/Libraries/Rio/en/System.Classes.TThread.AfterConstruction). I looked help in old versions of Delphi, there is the same. Unless in Delphi 1.0 it was not so.
It's also documented in FPC https://www.freepascal.org/docs-html/current/rtl/classes/tthread.afterconstruction.html (https://www.freepascal.org/docs-html/current/rtl/classes/tthread.afterconstruction.html)
So it is safe to call inherited Create(false) inside the constructor.
By the way, the statement "if CreateSuspended = false then Start;" is not correct (should be removed " = false")
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 17, 2019, 11:11:18 pm
So it is safe to call inherited Create(false) inside the constructor.
Good to know.

But if that's the case, the wiki is not correct.

It says...
Quote
AfterConstruction is overridden in TThread, it starts the thread if it was created in a suspended state.

Shouldn't it be "if it was created in a non suspended state" then?

In a suspended state the thread is only started after calling start.

Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 18, 2019, 05:43:06 am
A bit OOT, how to call procedure ThreadDone with parameter? Is it possible?

Previous code
Code: Pascal  [Select][+][-]
  1. TMainFrm = class(TForm)
  2.     btnStart: TButton;
  3.     procedure ThreadDone(Sender: TObject);
  4. end;
  5.  
  6. procedure TMainFrm.Go();
  7. var
  8.   Dt1 : TLocGetDtThr1;
  9. begin
  10.   Dt1 := TLocGetDtThr1.Create(True,@ThreadDone);  
  11. end;
  12.  

New Code
Code: Pascal  [Select][+][-]
  1. TMainFrm = class(TForm)
  2.     btnStart: TButton;
  3.     procedure ThreadDone(Sender: TObject; Thread:integer);
  4. end;

Look at the declaration of procedure ThreadDone, there is additional parameter. How to call it on variable Dt1?
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: Thaddy on June 18, 2019, 09:00:35 am
By the way, the statement "if CreateSuspended = false then Start;" is not correct (should be removed " = false")
??? Of course not. I set create suspended = true during setup and then test if the parameter assumes the thread should be started. But the remark of AfterConstruction I didn't know about.
The logic is the same, only in afterconstruction setup first, then call inherited afterconstruction. That also cannot overwrite things you need to setup.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: PascalDragon on June 18, 2019, 09:18:24 am
So it is safe to call inherited Create(false) inside the constructor.
Good to know.

But if that's the case, the wiki is not correct.
Then the wiki article needs to be fixed.

It says...
Quote
AfterConstruction is overridden in TThread, it starts the thread if it was created in a suspended state.

Shouldn't it be "if it was created in a non suspended state" then?

In a suspended state the thread is only started after calling start.
Please report a bug towards the documentation so that it isn't forgotten.
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 18, 2019, 09:57:29 am
A bit OOT, how to call procedure ThreadDone with parameter? Is it possible?
Not OT, and yes, it is possible. But not in the 'normal' way.

If you look at the TNotifyEvent as it is defined now you find:
Code: Pascal  [Select][+][-]
  1.   TNotifyEvent = procedure(Sender: TObject) of object;
So you see there is already one parameter you needed to provide.

When you want more/other parameters you need to define another procedure of your own.
Make sure it matches what you want exactly.

But the OnTerminate itself is private and can't be changed:
Code: Pascal  [Select][+][-]
  1. procedure TThread.CallOnTerminate;
  2. begin
  3.   FOnTerminate(Self);
  4. end;
So you can't any new parameters there.

You can create your own FMyTerminate methods.
Something like this. But note that there is a simpler way (see below).

Code: Pascal  [Select][+][-]
  1. type
  2.   TMyNotifyEvent = procedure(Sender: TObject; Thread:integer) of object;
  3.  
  4. type
  5.   TD3GetDtThr = class(TThread)
  6.   private
  7.     FMyTerminate: TMyNotifyEvent;
  8.     procedure CallMyTerminate;
  9.   protected
  10.     procedure Execute; override;
  11.     procedure DoTerminate; override; // we override DoTerminate to include calling our own MyTerminate
  12.   public
  13.     constructor Create(CreateSuspended: boolean; AThreadDone: TMyNotifyEvent); overload;
  14.     property MyTerminate: TMyNotifyEvent read FMyTerminate write FMyTerminate;
  15.   end;
  16.  
  17. constructor TD3GetDtThr.Create(CreateSuspended: boolean; AThreadDone: TMyNotifyEvent);
  18. begin
  19.   inherited Create(True);
  20.   FreeOnTerminate := True;
  21.   MyTerminate := AThreadDone; // prefix with @ if in Delphi mode
  22.   if not CreateSuspended then
  23.     Start;
  24. end;
  25.  
  26. procedure TD3GetDtThr.Execute;
  27. begin
  28.   //
  29. end;
  30.  
  31. procedure TD3GetDtThr.CallMyTerminate;
  32. begin
  33.   FMyTerminate(Self, 12345); // This is our own OnTerminate
  34. end;
  35.  
  36. procedure TD3GetDtThr.DoTerminate;
  37. begin
  38.   if Assigned(FMyTerminate) then
  39.     Synchronize(@CallMyTerminate);
  40.   inherited;
  41. end;

But as I said... it might be even simpler depending on your own code.

The TNotifyEvent has a Sender. The Sender of OnTerminate is always the TThread itself.
As can be seen from the source earlier.
Code: Pascal  [Select][+][-]
  1. FOnTerminate(Self); // the OnTerminate in the Thread passes itself to your OnTerminate procedure !!

So in your own ThreadDone you can access the Thread. Just make sure any variable you need are public.

Code: Pascal  [Select][+][-]
  1. procedure TMainFrm.ThreadDone(Sender: TObject);
  2. begin
  3.   if Sender is TD3GetDtThr then
  4.   begin
  5.     // here you can access TD3GetDtThr(Sender).Public_Variables
  6.   end;
  7. end;

Much simpler, isn't it  8-)
(Maybe I didn't need to explain the whole other method... but hey, we are here to learn  :P )

Please report a bug towards the documentation so that it isn't forgotten.
Done
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 18, 2019, 10:54:26 am
@rvk

Thanks a lot, I learn a lot today  :)
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 18, 2019, 12:15:15 pm
Hi guys,

Just wondering about Thread Create.
For example, I have these codes
Code: Pascal  [Select][+][-]
  1. constructor TD3GetDtThr.Create(CreateSuspended: boolean; AThreadDone: TNotifyEvent);
  2. begin
  3.   inherited Create(true);
  4.   FreeOnTerminate := true;
  5.   OnTerminate := AThreadDone;
  6.   Start;
  7. end;
  8.  
  9. // thread declaration
  10. Dt3 := TD3GetDtThr.Create( True,@ThreadDone);
  11. Dt3.Id1 := 1;
  12. Dt3.Id2 := 100;
  13.  

Even though thread Variables Id1 & Id2 declared after thread start, these variable still would be recognized by procedure TD3GetDtThr.Execute. How come?
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: rvk on June 18, 2019, 12:19:20 pm
Even though thread Variables Id1 & Id2 declared after thread start, these variable still would be recognized by procedure TD3GetDtThr.Execute. How come?
You can't be certain of that.
Maybe the TThread.Execute is already started, maybe not.
But I wouldn't count on it.

Try to put a sleep(1000) after the TD3GetDtThr.Create() and see what happens then.

(Now the Id1 and Id2 are assigned just microseconds after creating the thread and that could be just before the TThread.Execute, but don't count on that.)
Title: Re: [SOLVED] Error class 'external : SIGSEGV' when running Thread
Post by: incendio on June 19, 2019, 04:26:42 am
To be safe, I removed Start command from constructor, and only call it when all initialization process completed.
TinyPortal © 2005-2018