我认为这将是一个简单的,当你看到它的问题,但它让我感到困惑.
[停止新闻:我是对的.解决方案被发现.看到答案.]
我正在使用Python的unittest框架来测试多线程应用程序.很好,很直接 – 我有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” – 我看到提出了Division By Zero错误.我把它移到睡眠后,我从来没有看到过这个消息.
我想“好吧,也许其他线程试图同时记录非常大的东西,它仍在缓冲.它在做什么?”
那么,到目前为止,测试已经返回到unittest,在测试系统状态之前暂停等待线程开始.
logging.info("Test sleep starting")
time.sleep(0.25)
logging.info("Test waking up")
哇,看起来很熟悉.它以完全相同的方式冻结!第一条日志消息出现,第二条消息不出现.
我最近对该单元进行了重大改写,因此我无法声称“我没有触及任何东西”,但我在改变中看不出任何不妥之处.
可疑区域:
>我包括使用Threading.Lock(因为我不知道如何推理GIL的安全性,所以我坚持我所知道的.我没有看到任何关于我的代码的“僵局”.
>我是Python的unittest框架的新手.它是否可以通过重定向日志记录或类似功能来模拟这些症状?
>不,我没有替换非标准时间模块!
什么会阻止一个线程醒来?我还错过了什么?
最佳答案 叹.
工人线程#1正在睡觉,然后醒来.然后它将记录唤醒消息,并被阻止.一次只能记录一个线程.
UnitTest Thread正在睡觉,然后醒来.然后它将记录唤醒消息,并被阻止.一次只能记录一个线程.
工作者 – 线程 – 先前未提及 – 问题#2正在悄悄地完成处理队列中的PREVIOUS项目,而第一个工作线程正在休眠.它得到了一个日志声明.其中一个参数是一个对象,并且隐式调用了str().该对象的str()函数有一个bug;它访问了一些数据成员时陷入僵局.在由日志记录功能处理时发生死锁,从而保持日志记录线程锁定,并使其看起来像其他线程永远不会醒来.
零测试除法没有区别,因为它的结果是尝试记录.