freelanceprogrammers.org Forum Index » Delphi
TPythonEngine / TThread
Joined: 24 Apr 2005
Posts: 12
TPythonEngine / TThread
Hi,
I created a TThread-derived class that creates a TPythonEngine instance and
executes Python code. It works fine. If another instance of my derived
thread class is created (after the first one finished and is destroyed),
however, I receive the error: `No engine defined for component ""`.
Here is the code that works the first time, but not the second time it is
called:
Constructor
=========
constructor TXcComThread.Create;
begin
inherited Create(true);
FHtml := TStringList.Create;
FStrings := TStringList.Create;
FPyEngine := TPythonEngine.Create(nil);
FPyEngine.AutoFinalize := False;
FPyEngine.LoadDll;
FPyVar := TPythonDelphiVar.Create(nil);
FPyVar.VarName := `result`;
FPyVar.Engine := FPyEngine;
FPyVar.Initialize;
end;
Destructor
========
destructor TXcComThread.Destroy;
begin
FPyVar.Free;
FPyEngine.Free;
FStrings.Free;
FHtml.Free;
inherited;
end;
I suspect the Python engine and the variable are not properly destroyed when
the thread finishes execution, but the thread`s constructor is called
properly and according to the P4D example code ".Free" seems to be
sufficient.
The exception is thrown when "FPyVar.Initialize" is called:
Call stack
========
TEngineClient.CheckEngine
TPythonType.CreateInstance
TPythonDelphiVar.CreateVar
TPythonDelphiVar.Initialize
I`m properly doing something very wrong ...
Thanks in advance,
-Andreas
Joined: 29 Apr 2005
Posts: 103
TPythonEngine / TThread
Hi Andreas,
I could reproduce the bug with the following code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, PythonEngine, StdCtrls;
type
TXcComThread = class(TThread)
protected
FPyEngine : TPythonEngine;
FPyVar : TPythonDelphiVar;
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
constructor TXcComThread.Create;
begin
inherited Create(True);
FPyEngine := TPythonEngine.Create(nil);
//FPyEngine.AutoFinalize := False;
FPyEngine.LoadDll;
FPyVar := TPythonDelphiVar.Create(nil);
FPyVar.VarName := `result`;
FPyVar.Engine := FPyEngine;
FPyVar.Initialize;
end;
destructor TXcComThread.Destroy;
begin
FPyVar.Free;
FPyEngine.Free;
inherited;
end;
procedure TXcComThread.Execute;
begin
FPyEngine.ExecString(`for i in xrange(10000): pass`);
MessageBeep(0);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
T : TXcComThread;
begin
for i := 1 to 1000 do
begin
T := TXcComThread.Create;
T.Resume;
T.Free;
end;
end;
end.
There is indeed a problem with a cached TPythonType that was not properly
cleaned up.
I fixed it but then it crashed unless you remove your
FPyEngine.AutoFinalize := False;
Then I could run it several times, but if you run it a lot of times and
watch the memory consumption, you`ll see that it`s leaking a lot.
This is a problem of Python. It`s not well designed for being
initialized/finalized multiple times.
And if you set AutoFinalize to False, it means that P4D won`t finalize
Python and try to reinitialize it the next time. If you don`t finalize
Python, then why would you create several instances of TPythonEngine?
Even if everything`s successful, you`ll have to be very careful with
multithreading as this hasn`t been tested in this context...
So, my advice would be to create a single thread that would queue script
execution requests. Make sure that anything that gets executed by Python
won`t have direct access to VCL objects as they`re not thread safe!
Bye,
Morgan
> -----Original Message-----
> From: pythonfordelphi@yahoogroups.com
> [mailto:pythonfordelphi@yahoogroups.com] On Behalf Of Andreas Schmid
> Sent: April 29, 2005 10:07 AM
> To: pythonfordelphi@yahoogroups.com
> Subject: [pythonfordelphi] TPythonEngine / TThread
>
> Hi,
>
> I created a TThread-derived class that creates a TPythonEngine instance
> and
> executes Python code. It works fine. If another instance of my derived
> thread class is created (after the first one finished and is destroyed),
> however, I receive the error: `No engine defined for component ""`.
>
> Here is the code that works the first time, but not the second time it is
> called:
>
> Constructor
> =========
>
> constructor TXcComThread.Create;
> begin
> inherited Create(true);
> FHtml := TStringList.Create;
> FStrings := TStringList.Create;
>
> FPyEngine := TPythonEngine.Create(nil);
> FPyEngine.AutoFinalize := False;
> FPyEngine.LoadDll;
>
> FPyVar := TPythonDelphiVar.Create(nil);
> FPyVar.VarName := `result`;
> FPyVar.Engine := FPyEngine;
> FPyVar.Initialize;
> end;
>
> Destructor
> ========
>
> destructor TXcComThread.Destroy;
> begin
> FPyVar.Free;
> FPyEngine.Free;
>
> FStrings.Free;
> FHtml.Free;
> inherited;
> end;
>
> I suspect the Python engine and the variable are not properly destroyed
> when
> the thread finishes execution, but the thread`s constructor is called
> properly and according to the P4D example code ".Free" seems to be
> sufficient.
>
> The exception is thrown when "FPyVar.Initialize" is called:
>
> Call stack
> ========
>
> TEngineClient.CheckEngine
> TPythonType.CreateInstance
> TPythonDelphiVar.CreateVar
> TPythonDelphiVar.Initialize
>
> I`m properly doing something very wrong ...
>
> Thanks in advance,
>
> -Andreas
>
>
>
>
>
>
>
>
> To Post a message, send it to: pythonfordelphi@eGroups.com
>
> To Unsubscribe, send a blank message to: pythonfordelphi-
> unsubscribe@eGroups.com
> Yahoo! Groups Links
>
>
>
>
>
>
All times are GMT
Page 1 of 1
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Freelace Website Designer - Customer web design and software building.
China Wholesale - Electronics Products
Character Studio - Tutorials and Help
China Wholesale - Electronics Products
Character Studio - Tutorials and Help







