Python嵌入线程-避免死锁? [英] Python embedding with threads -- avoiding deadlocks?

查看:185
本文介绍了Python嵌入线程-避免死锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there any way to embed python, allow callbacks from python to C++, allowing the Pythhon code to spawn threads, and avoiding deadlocks?

问题是这样的:

  • 要调用Python,我需要按住GIL.通常,我是通过在首次创建解释器时获取主线程状态,然后使用PyEval_RestoreThread()来获取GIL并在调用Python之前交换线程状态来实现的.

  • To call into Python, I need to hold the GIL. Typically, I do this by getting the main thread state when I first create the interpreter, and then using PyEval_RestoreThread() to take the GIL and swap in the thread state before I call into Python.

从Python调用时,我可能需要访问一些受保护的资源,这些资源受主机中单独的关键部分保护.这意味着Python将保留GIL(可能从我最初调用的其他线程中保留),然后尝试获取我的保护锁.

When called from Python, I may need to access some protected resources that are protected by a separate critical section in my host. This means that Python will hold the GIL (potentially from some other thread than I initially called into), and then attempt to acquire my protection lock.

在调用Python时,我可能需要持有相同的锁,例如,因为我可能正在遍历一些对象集合.

When calling into Python, I may need to hold the same locks, because I may be iterating over some collection of objects, for example.

问题在于,即使我在调用Python时握住GIL,Python也会放弃它,将其交给另一个线程,然后将该线程调用到我的主机中,期望获得主机锁.同时,主机可以获取主机锁和GIL锁,然后调用Python.死锁随之而来.

The problem is that even if I hold the GIL when I call into Python, Python may give it up, give it to another thread, and then have that thread call into my host, expecting to take the host locks. Meanwhile, the host may take the host locks, and the GIL lock, and call into Python. Deadlock ensues.

这里的问题是当我调用GIL时,Python会将GIL放弃给另一个线程.这就是预期的操作,但是它无法进行序列锁定-即使我先使用GIL,然后获取自己的锁,然后调用Python,Python也会从另一个线程调用我的系统,并期望获取自己的锁(因为它通过释放GIL来取消对GIL的排序).

The problem here is that Python relinquishes the GIL to another thread while I've called into it. That's what it's expected to do, but it makes it impossible to sequence locking -- even if I first take GIL, then take my own lock, then call Python, Python will call into my system from another thread, expecting to take my own lock (because it un-sequenced the GIL by releasing it).

我无法真正让系统的其余部分使用GIL来锁定系统中的所有可能的锁-甚至无法正常工作,因为Python可能仍会将其释放到另一个线程.

I can't really make the rest of my system use the GIL for all possible locks in the system -- and that wouldn't even work right, because Python may still release it to another thread.

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

I can't really guarantee that my host doesn't hold any locks when entering Python, either, because I'm not in control of all the code in the host.

那么,仅仅是这种情况无法完成?

So, is it just the case that this can't be done?

推荐答案

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

The code that is called by python should release the GIL before taking any of your locks. That way I believe it can't get into the dead-lock.

这篇关于Python嵌入线程-避免死锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆