gpt4 book ai didi

python - 在多线程 C 应用程序中嵌入 python

转载 作者:IT老高 更新时间:2023-10-28 21:13:57 31 4
gpt4 key购买 nike

我将 python 解释器嵌入到一个多线程 C 应用程序中,我有点困惑应该使用哪些 API 来确保线程安全。

根据我收集到的信息,在嵌入 python 时,在调用任何其他 Python C API 调用之前,由嵌入器负责处理 GIL 锁。这是通过以下函数完成的:

gstate = PyGILState_Ensure();
// do some python api calls, run python scripts
PyGILState_Release(gstate);

但仅此一项似乎还不够。我仍然遇到随机崩溃,因为它似乎没有为 Python API 提供互斥。

在阅读了更多文档后,我还添加了:

PyEval_InitThreads();

在调用 Py_IsInitialized() 之后但这就是令人困惑的部分。文档声明此功能:

Initialize and acquire the global interpreter lock

这表明当这个函数返回时,GIL 应该被锁定并且应该以某种方式解锁。但实际上这似乎不是必需的。有了这条线,我的多线程工作完美,PyGILState_Ensure/Release 维护了互斥。功能。
当我尝试添加 PyEval_ReleaseLock()PyEval_ReleaseLock() 之后在随后对 PyImport_ExecCodeModule() 的调用中,应用程序很快就死锁了。 .

那么我在这里错过了什么?

最佳答案

我遇到了完全相同的问题,现在可以通过在 PyEval_InitThreads() 之后立即使用 PyEval_SaveThread() 来解决,正如您上面建议的那样。但是,我的实际问题是我在 PyInitialise() 之后使用了 PyEval_InitThreads() ,然后导致 PyGILState_Ensure() 在从其他地方调用时阻塞,后续的 native 线程。总之,这就是我现在所做的:

  1. 有全局变量:

    static int gil_init = 0; 
  2. 从主线程加载原生 C 扩展并启动 Python 解释器:

    Py_Initialize() 
  3. 我的应用同时从多个其他线程对 Python/C API 进行大量调用:

    if (!gil_init) {
    gil_init = 1;
    PyEval_InitThreads();
    PyEval_SaveThread();
    }
    state = PyGILState_Ensure();
    // Call Python/C API functions...
    PyGILState_Release(state);
  4. 从主线程停止 Python 解释器

    Py_Finalize()

我尝试过的所有其他解决方案都使用 PyGILState_Ensure() 导致随机 Python sigfaults 或死锁/阻塞。

Python 文档确实应该对此更加清楚,并且至少为嵌入和扩展用例提供了一个示例。

关于python - 在多线程 C 应用程序中嵌入 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10625584/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com