[英]Python.Net: Do I need "using (Py.GIL())" in a callback from .Net to Python?
[英]Python.net "GIL" lifetime and multiple instances
我的桌面應用程序使用 IronPython 來執行各種腳本功能,但我們面臨支持 Numpy 的壓力(這對於 IP 是不可能的),所以我目前正在研究 Python.Net,但我有點不清楚如何管理 GIL 等對象的生命周期。 Python.Net C# 示例通常如下所示:
using (Py.Gil())
{
using (var scope = Py.CreateScope())
{
// Do everything in here
}
}
我寫了一個 class 封裝了 Python 代碼的運行,大致看起來像這樣(為簡潔起見刪除了錯誤處理等):
public class ScriptRunner()
{
private readonly PyModule _scope;
private readonly Py.GILState _gil;
private PyObject _compiledScript;
public ScriptRunner()
{
_gil = Py.GIL();
_scope = Py.CreateScope();
}
public Dispose()
{
_scope?.Dispose();
_gil?.Dispose();
}
public void SetVariable(string name, object value)
{
_scope.Set(name, value);
}
public void PrepareScript(string pythonCode)
{
_compiledScript = PythonEngine.Compile(pythonCode);
}
public void ExecuteScript()
{
_scope.Execute(_compiledScript);
}
}
我的應用程序中的代碼多次執行相同的 Python 代碼是很常見的,但具有不同的變量值,因此上述 class 的典型用法如下所示:
_scriptRunner.PrepareScript(myPythonCode);
_scriptRunner.SetVariable("x", 123);
_scriptRunner.ExecuteScript();
_scriptRunner.SetVariable("x", 456);
_scriptRunner.ExecuteScript();
...
在我的應用程序中將有許多 class 的實例,在需要執行 Python 代碼的任何地方使用。 我主要關心的是“GIL”生命周期方面,我不太了解。 上述設計是否意味着實際上只有一個實例能夠工作(具有 GIL“句柄”的實例)?
我想知道是否應該添加顯式方法來創建和釋放這些對象,而不是在構造函數和 Dispose() 中管理 GIL(和范圍)object 生命周期,例如:
public void Initialise()
{
_gil = Py.GIL();
_scope = Py.CreateScope();
}
public Free()
{
_scope?.Dispose();
_gil?.Dispose();
}
用法最終會更像這樣,其中 GIL 僅在工作期間“鎖定”(如果這是正確的詞):
_scriptRunner.Initialise();
_scriptRunner.PrepareScript(myPythonCode);
_scriptRunner.SetVariable("x", 123);
_scriptRunner.RunScript();
_scriptRunner.SetVariable("x", 456);
_scriptRunner.RunScript();
...
_scriptRunner.Free();
想法?
一次只能存在並激活一個GIL
實例。 using GIL
的行為類似於 C# lock
語句。 https://learn.microsoft.com/en-us/do.net/csharp/language-reference/statements/lock
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.