Python time.sleep - 永不醒来

标签 python multithreading deadlock sleep

我认为这将是那些简单的当你看到它的问题之一,但它让我感到困惑。

[停止新闻:我是对的。找到解决方案。查看答案。]

我正在使用 Python 的单元测试框架来测试多线程应用程序。很好,很直接——我有 5 个左右的工作线程监视一个公共(public)队列,一个生产者线程为它们制作工作项。生产者线程由测试用例触发。

在这个测试中,只有一个任务被放入队列。它在测试中所做的处理只是真正处理的 stub ,因此工作线程会进行 5 秒 sleep 以模拟任务真正完成之前耗时,线程将准备好获取另一个任务.

代码片段是:

 logging.info("Sleep starting")
 time.sleep(5)
 logging.info("Waking up")

现在是奇怪的部分。我看到“ sleep 开始”日志消息,但没有看到唤醒消息。程序锁定并且不响应键盘中断 (CTRL+C)。 CPU 负载很低。

我在 Windows 和 Ubuntu (Python 2.6.2) 中看到同样的问题。

我考虑过异常是否正在发生并被隐藏,所以我在第一行和第二行之间添加了“print 1/0”——我看到出现了被零除错误。我把它移到 sleep 后,但我从未看到消息。

我想“好吧,也许另一个线程正在尝试同时记录非常非常大的内容,并且它仍在缓冲。它在做什么?”

好吧,此时,测试已经返回到单元测试,它暂停等待线程开始运行,然后再测试系统状态。

 logging.info("Test sleep starting")
 time.sleep(0.25)
 logging.info("Test waking up")

哇,这看起来很熟悉。它以完全相同的方式卡住!第一条日志消息出现,第二条没有。

我最近对该单元进行了重大重写,因此我不能声称“我没有触及任何东西”,但我看不出我的更改有任何不妥之处。

可疑区域:

  • 我包括使用 Threading.Lock(因为我不知道如何推理 GIL 的安全性,所以我坚持我所知道的。我没有看到我的代码有任何“僵局”。

  • 我是 Python 单元测试框架的新手。它是否对重定向日志记录或可能模拟这些症状的类似行为做了什么?

  • 不,我没有替换非标准时间模块!

什么会阻止线程唤醒?我还错过了什么?

最佳答案

感叹。

工作线程 #1 正在休眠,然后醒来。然后它将记录唤醒消息,并被阻止。一次只能记录一个线程。

UnitTest 线程正在休眠,然后醒来。然后它将记录唤醒消息,并被阻止。一次只能记录一个线程。

Worker-Thread-Not-Previously-Mentioned-In-The-Question #2 正在安静地完成处理队列中的 PREVIOUS 项目,而第一个 Worker 线程正在休眠。它得到了一个日志语句。其中一个参数是一个对象,并且隐式调用了 str()。该对象的 str() 函数有一个错误;它在访问其某些数据成员时陷入僵局。死锁是在日志函数处理时发生的,因此保持日志线程锁定,并使其看起来像其他线程从未醒来。

除以零测试没有影响,因为它的结果是尝试记录。

关于Python time.sleep - 永不醒来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2342397/

相关文章:

python Win32 保存

python - 使用 optparse 的带有可选参数的命令行选项

c++ - MFC:从另一个线程调用 CWnd 方法是否安全?

linux - 如何确保信号处理程序永远不会屈服于同一进程组中的线程?

celery - 如果传感器数量大于并发数,Airflow celery Worker 会被阻塞吗?

python - 使用正则表达式删除日期周围的括号

python - 使用千位分隔符对数字行进行排序

java - 使用 Java 中的生产者和消费者防止有界执行程序服务中可能发生的死锁情况

java - 如何避免数据库死锁

c++ - MiniDumpWriteDump() 挂起