我有一个 Python 脚本,其中包含一些通过队列链接在一起的线程。其中一个线程有一个 MySQLdb 连接,该连接在线程的初始化函数中使用,也在线程的主循环中的主循环中使用。
现在,当脚本运行时,MySQLdb 连接在线程的初始化部分工作得很好。但是当它在线程的主循环中使用时,它会在 self.cursor.execute(SQL)
行上完全死锁。现在,当我在死锁后按下 Ctrl-C 时,事情变得更加奇怪了。然后死锁被打破,MySQLdb 游标得到它的结果,线程继续正常运行,直到 KeyboardInterupt 被捕获。
我以前多次使用相同的代码,但这是我第一次在其中使用 MySQLdb。我以前从未遇到过这种行为,而且我在试图理解这里发生的事情时不知所措。如果我有一些异常(exception)可以引用是一回事,但没有。另外,我真的不明白为什么 self.cursor.execute(SQL)
行在我按下 Ctrl-C 后实际上返回了正确的值。
我无权展示实际代码,但请相信我,它非常简单明了,没有任何多余的装饰。线程的主循环只是一个带有 Queue get 函数的 while 循环,紧接着是一个 MySQLdb 查询。这似乎不是 SQL 问题,因为我已尝试使用最简单的 SELECT 'hello'
查询,它仍然会导致相同的行为。
此行为的原因可能是什么?
FWIW,我使用的是 Python 2.7,我在 OS X/Ubuntu 11.10 上得到了相同的行为。
编辑: 我开始怀疑这是否是由 MySQL 服务器设置引起的。我刚刚尝试使用另一个 Python MySQL 库 (pymysql),它给出了相同的行为。
EDIT2: 我刚刚重启了 MySQL 服务器,发现日志查询很慢。奇怪的是,我可以看到其他查询,但阻止的查询没有显示。
EDIT3:[解决了某种] 我找到了 this详细说明如何查看线程正在做什么的方法。经过一些调试后,很明显罪魁祸首是 MySQLdb 模块中的导入。然后我简单地注释掉了 MySQLdb/cursors.py 中的第 83-95 行,它突然工作正常了。我不认为这些行无论如何都那么重要,因为它们似乎只呈现一些警告,而且我确信我正在运行的这些特定查询的质量。
如果有人真的知道解决这个问题的更可靠的方法,我很乐意听听。
最佳答案
可能是您正在共享线程之间的连接。 MySQLdb documents推荐
Don't share connections between threads. It's really not worth your effort or mine, and in the end, will probably hurt performance, since the MySQL server runs a separate thread for each connection. You can certainly do things like cache connections in a pool, and give those connections to one thread at a time. If you let two threads use a connection simultaneously, the MySQL client library will probably upchuck and die. You have been warned.
关于python - 如何解决 Python 线程中这种奇怪的 MySQL 锁定行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9906375/