我认为这将是那些简单的问题之一,但它让我感到困惑。
[ 停止媒体:我是对的。找到了解决方案。查看答案。 ]
我正在使用 Python 的单元测试框架来测试多线程应用程序。很好而且很直接 - 我有 5 个左右的工作线程监视一个公共队列,以及一个为它们制作工作项的生产者线程。生产者线程由测试用例触发。
在此测试中,只有一个任务被放入队列中。它在测试中所做的处理只是真正处理的存根,因此工作线程会进行 5 秒的睡眠来模拟任务真正完成之前经过的时间,并且线程将准备好获取另一个任务.
代码片段是:
logging.info("Sleep starting")
time.sleep(5)
logging.info("Waking up")
现在是奇怪的部分。我看到“睡眠开始”日志消息,但没有看到唤醒消息。程序锁定并且不响应键盘中断 (CTRL+C)。 CPU 负载非常低。
我在 Windows 和 Ubuntu (Python 2.6.2) 中看到同样的问题。
我思考是否发生了异常并被隐藏,所以我在之间添加了“print 1/0”第一行和第二行 - 我看到引发了除零错误。我将其移至睡眠后,但从未看到该消息。
我想“好吧,也许另一个线程正在尝试同时记录非常大的内容,并且它仍在缓冲。它在做什么?”
好吧,此时,测试已返回到单元测试,在测试系统状态之前,它会暂停等待线程开始运行。
logging.info("Test sleep starting")
time.sleep(0.25)
logging.info("Test waking up")
哇,这看起来很熟悉。它以完全相同的方式冻结!第一条日志消息出现,第二条没有出现。
我最近对单元进行了重大重写,所以我不能声称“我没有碰任何东西”,但我在其中看不到任何异常。我的更改。
可疑区域:
-
我包括使用 Threading.Lock (因为我不知道如何推理 GIL 的安全性,所以我坚持我所知道的。我认为我的代码没有任何“死锁” .
-
我是 Python 的单元测试框架的新手,它是否可以通过重定向日志记录或类似的方式来模拟这些症状?
-
不,我还没有替换非标准时间模块!
会发生什么?阻止线程醒来?我还错过了什么?
已解决: 问题出在我的单元测试中。我有一个在测试方法执行后运行的“tearDown”方法。它加入了工作线程,超时为 1 秒(以防出现问题)。
事实证明,从线程内部加入线程是行不通的 - 整个测试运行都停止了,直到线程完成(此时它永远不会完成,因为它正在等待自己完成)。
感谢所有提出建议的人。我接受了在单独的进程中运行工作代码的建议,这让我找到了问题所在。
标签:python,multithreading,deadlock,sleep From: 2342397