7

有没有办法嵌入 python,允许从 python 到 C++ 的回调,允许 Pythhon 代码产生线程,并避免死锁?

问题是这样的:

  • 要调用 Python,我需要持有 GIL。通常,我首先创建解释器时获取主线程状态,然后使用 PyEval_RestoreThread() 获取 GIL 并在调用 Python 之前交换线程状态。

  • 从 Python 调用时,我可能需要访问一些受主机中单独的临界区保护的受保护资源。这意味着 Python 将持有 GIL(可能来自我最初调用的其他线程),然后尝试获取我的保护锁。

  • 当调用 Python 时,我可能需要持有相同的锁,因为我可能正在迭代某些对象集合。

问题是,即使我在调用 Python 时持有 GIL,Python 也可能会放弃它,将其交给另一个线程,然后让该线程调用我的主机,期望获取主机锁。同时,主机可以获取主机锁和 GIL 锁,并调用 Python。出现僵局。

这里的问题是,当我调用 GIL 时,Python 将 GIL 放弃给另一个线程。这就是它所期望的,但是它使得顺序锁定成为不可能——即使我首先使用 GIL,然后使用我自己的锁,然后调用 Python,Python 将从另一个线程调用我的系统,期望使用我自己的锁(因为它通过释放 GIL 来取消对 GIL 的排序)。

我不能真正让我的系统的其余部分使用 GIL 来处理系统中所有可能的锁——这甚至不能正常工作,因为 Python 可能仍会将它释放到另一个线程。

我也不能真正保证我的主机在进入 Python 时不会持有任何锁,因为我无法控制主机中的所有代码。

那么,难道就只有这样就做不到了吗?

4

3 回答 3

2

“当调用 Python 时,我可能需要持有相同的锁,因为我可能正在迭代某些对象集合。”

这通常表明具有多个线程的单个进程是不合适的。也许在这种情况下,多个进程——每个进程都有一个来自集合的特定对象——更有意义。

独立的进程——每个都有自己的线程池——可能更容易管理。

于 2009-04-29T18:44:19.803 回答
2

python 调用的代码应该在获取任何锁之前释放 GIL。这样我相信它不会陷入僵局。

于 2009-04-29T21:49:50.637 回答
-1

There was recently some discussion of a similar issue on the pyopenssl list. I'm afraid if I try to explain this I'm going to get it wrong, so instead I'll refer you to the problem in question.

于 2009-04-30T18:53:15.793 回答