gpt4 book ai didi

python - 如何用 gevent 和 oursql 解决这个死锁

转载 作者:太空宇宙 更新时间:2023-11-03 19:03:04 25 4
gpt4 key购买 nike

我有一个复杂项目的以下代码:

from gevent import monkey
monkey.patch_all()
import gevent

import oursql

def run(num):
conn = oursql.connect(host = ...)
cursor = conn.cursor()
cursor.execute('start transaction')
for i in range(2):
print num, i
cursor.execute('UPDATE userobj SET timestamp=(timestamp + 1) WHERE id = 1')
gevent.sleep()

cursor.execute('rollback')


proc = [gevent.spawn(run, i) for i in range(2)]
gevent.wait(proc)

引擎是InnoDB,输出是:

0 0
1 0

然后程序挂起。我知道原因是mysql在第一个greenlet执行更新语句后锁定了该行,因此另一个greenlet中的更新将被阻塞。但是为什么在第一个 greenlet 在套接字上阻塞后,gevent 不将控制权转移回第一个 greenlet 呢?我想知道除了在 gevent.sleep 之前使用锁或提交之外,还有什么优雅的解决方案吗?

附:原来的情况是在一个网站项目中。我混合了 pymongo 和 SQLAlchemy 操作,并使用 Gunicorn 为该站点提供服务。但我发现并行请求可能会永远阻塞。经过长时间的调试,我终于弄清楚这是由于pymongo使用了一些socket操作,导致gevent切换到另一个greenlet,从而导致了死锁,如上面的代码所示。

谢谢!

最佳答案

感谢@robertklep,一种可能的解决方案是用一些纯Python驱动程序(例如pymysql)替换oursql。事实上,oursql 是用 C 编写的,因此与 gevent 不兼容。

关于python - 如何用 gevent 和 oursql 解决这个死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15544238/

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