Soulflesh 1 Posted July 16, 2021 Hi, I have a problem running Python scripts in threads. The execution stucks in TPythonThread.Execute --> gilstate := PyGILState_Ensure(); and never return. Here is my example console application. program p4dtest; {$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Classes, PythonEngine; type TMyPythonThread = class(TPythonThread) protected procedure ExecuteWithPython; override; public constructor Create; end; TMyServiceHelper = class public ThreadCount : Integer; public procedure ThreadDone(Sender: TObject); end; { TMyPythonThread } constructor TMyPythonThread.Create; begin Self.ThreadExecMode := emNewInterpreter; Self.FreeOnTerminate := true; inherited Create(true); end; procedure TMyPythonThread.ExecuteWithPython; begin Writeln('Test1'); GetPythonEngine.ExecString('print("Test2")'); end; { TMyServiceHelper } procedure TMyServiceHelper.ThreadDone(Sender: TObject); begin Dec(ThreadCount); end; var MyPythonEngine : TPythonEngine; MyPyInOut : TMyPythonGUIInputOutput; MySvcHelper : TMyServiceHelper; Threads : Array of TMyPythonThread; i : Integer; begin try MyPythonEngine := TPythonEngine.Create(nil); MySvcHelper := TMyServiceHelper.Create; try MyPythonEngine.InitThreads := true; MyPythonEngine.LoadDll; MySvcHelper.ThreadCount := 1; SetLength(Threads,1); for i:=0 to 0 do begin Threads[i] := TMyPythonThread.Create; Threads[i].OnTerminate := MySvcHelper.ThreadDone; Threads[i].Start; end; repeat CheckSynchronize; sleep(10); until MySvcHelper.ThreadCount = 0; Writeln('Done'); ReadLn; finally FreeAndNil(MyPythonEngine); FreeAndNil(MySvcHelper); end; except on E: Exception do begin Writeln(E.ClassName, ': ', E.Message); ReadLn; end; end; end. Any ideas? Best regards. Share this post Link to post
pyscripter 689 Posted July 16, 2021 You need to call PyBeginAllowThreads in the main thread. Share this post Link to post
Soulflesh 1 Posted July 16, 2021 Unfortunately I cannot find anything like "PyBeginAllowThreads" or "AllowThreads" in all sources... 🤔 Share this post Link to post
pyscripter 689 Posted July 16, 2021 (edited) 3 hours ago, Soulflesh said: Unfortunately I cannot find anything like "PyBeginAllowThreads" or "AllowThreads" in all sources class procedure TPythonThread.Py_Begin_Allow_Threads; You also need to call Py_End_Allow_Threads when all threads finish. Edited July 16, 2021 by pyscripter 1 Share this post Link to post
Soulflesh 1 Posted July 17, 2021 Thank you very much. That solves my issue! Share this post Link to post
Soulflesh 1 Posted July 17, 2021 Additional question: 😀 I did some performance tests and unfortunately came to the expected result that normal thread processing does not bring any significant performance benefits. For my test I used the Fibonacci algorithm to generate a high CPU load and a low IO load. Are there ways, apart from additional processes, to improve the performance of parallel processing? I am talking here in the context of processing a wide variety of scripts or problems that cannot be parallelized themselves. Is there a possibility to use Python derivatives like CPython or IronPython without or with a disableableable GIL? From another area of resource sharing of dll libraries, a viable way was to duplicate the dll's and load them multiple times. Would this also be a possible approach here with Python and Delphi? Best regards Share this post Link to post
pyscripter 689 Posted July 17, 2021 (edited) Hard to answer this question in a meaningful way, since it depends a great deal on what you are trying to do. In general though: you can code performance critical computations in Delphi. See python4delphi/Tutorials/Webinar I at master · pyscripter/python4delphi (github.com) for an example of speeding up python code 60 times doing this. use python modules coded in C (or other compiled languages) that can spread computations to multiple cores. Edited July 17, 2021 by pyscripter Share this post Link to post
Soulflesh 1 Posted July 19, 2021 My topic is more in the sense of a web service, whereby it is more a matter of the overall speed and less of that of individual processes. In my view, true parallelism is the only way here. Share this post Link to post
hschmid67 0 Posted November 5, 2021 Hello, I'm looking for something similar - implementing python scripts in webservice procedures. Were You able to find a solution for this and would You mind to share it? Regards Harald Share this post Link to post
David Heffernan 2345 Posted November 5, 2021 19 minutes ago, hschmid67 said: I'm looking for something similar - implementing python scripts in webservice procedures. Were You able to find a solution for this and would You mind to share it? Why are you looking to use threads? What problem are you trying to solve with threads? Are you aware of the impact of the Python GIL? 1 Share this post Link to post
Soulflesh 1 Posted November 5, 2021 3 hours ago, hschmid67 said: Hello, I'm looking for something similar - implementing python scripts in webservice procedures. Were You able to find a solution for this and would You mind to share it? Regards Harald Hello Harald, Unfortunately, I have not yet found a way to implement this. I think at the moment the only possibility would be, as I wrote at the time, to multiply the dlls and then load them several times so that you have an independent dll environment for each thread. However, this would probably mean quite a lot of effort to rewrite this in the core libraries. Many greetings Share this post Link to post
Joseph MItzen 251 Posted November 5, 2021 On 7/17/2021 at 5:07 PM, Soulflesh said: I did some performance tests and unfortunately came to the expected result that normal thread processing does not bring any significant performance benefits. Threads are evil. Threading was never originally intended for general parallel processing. In Python, what you want is multiprocessing; performant and safe. Threading in Python will only improve IO-intensive tasks. Share this post Link to post
Joseph MItzen 251 Posted November 5, 2021 On 7/17/2021 at 6:45 PM, pyscripter said: you can code performance critical computations in Delphi. See python4delphi/Tutorials/Webinar I at master · pyscripter/python4delphi (github.com) for an example of speeding up python code 60 times doing this. Ooh thanks; this will be very interesting to check out. I sometimes use Cython or jitted Python (Numba) to speed up old Delphi or FreePascal code. Share this post Link to post
hschmid67 0 Posted November 7, 2021 On 11/5/2021 at 9:29 AM, David Heffernan said: Why are you looking to use threads? What problem are you trying to solve with threads? Are you aware of the impact of the Python GIL? Hello, I have a REST web server written in XData (TMS) and would like to execute a Python script in a service request (ActiveDirectory - using pyad). This would be in a thread - and I cannot be sure that there would not be a parallel request that executes Python in a different thread... So it seems to me that the only way to prevent problems with parallel python calls would be to use an object pool for python requests with just one element in the pool. The other request has to wait for the first to finish... Regards Harald Share this post Link to post
beginner1390 0 Posted November 24, 2021 Hello, I want to make API server via Delphi, run Python code per http requests at same time ... Can I do it with Delphi and Python ? thanks Share this post Link to post