代码干货 | 一个Reentrant Error引发的对Python信号机制的探索和思考
2017-09-18 13:56
579 查看
本文来源于阿里云-云栖社区,原文点击这里。
前几天工作时遇到了一个匪夷所思的问题。经过几次尝试后问题得以解决,但问题产生的原因却仍令人费解。查找 SO 无果,我决定翻看
Python 的源码。断断续续地研究了几天,终于恍然大悟。撰此文以记。
本文环境:
Ubuntu 16.04 (64 bit)
Python 3.6.2
使用的 C 源码可以从 Python 官网 获取。
起因
工作时用到了 celery 作为异步任务队列,为方便调试,我写了一个脚本用以启动/关闭 celery 主进程。代码简化后如下:
import sys
import subprocess
# ...
celery_process = subprocess.Popen(
['celery', '-A', 'XXX', 'worker'],
stdout=subprocess.PIPE,
stderr=sys.stderr
)
try:
# Start and wait for server process
except KeyboardInterrupt:
# Ctrl + C pressed
celery_process.terminate()
celery_process.wait()
代码启动了 celery worker,并尝试在捕获到
KeyboardInterrupt 异常时将其热关闭。
初看上去没什么问题。然而实际测试时却发生了十分诡异的事情:按下 Ctrl+C 后,程序 偶尔 会抛出这样的异常:RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>’>。诡异之处有两点:
异常发生的时机有随机性
异常的 traceback 指向 celery 包,也就是说这是在 celery 主进程内部发生的异常
这个结果大大出乎了我的意料。随机性异常是众多最难缠的问题之一,因为这常常意味着并发问题,涉及底层知识,病灶隐蔽,调试难度大,同时没有有效的手段判断问题是否彻底解决(可能只是降低了频率)。
展开全文
前几天工作时遇到了一个匪夷所思的问题。经过几次尝试后问题得以解决,但问题产生的原因却仍令人费解。查找 SO 无果,我决定翻看
Python 的源码。断断续续地研究了几天,终于恍然大悟。撰此文以记。
本文环境:
Ubuntu 16.04 (64 bit)
Python 3.6.2
使用的 C 源码可以从 Python 官网 获取。
起因
工作时用到了 celery 作为异步任务队列,为方便调试,我写了一个脚本用以启动/关闭 celery 主进程。代码简化后如下:
import sys
import subprocess
# ...
celery_process = subprocess.Popen(
['celery', '-A', 'XXX', 'worker'],
stdout=subprocess.PIPE,
stderr=sys.stderr
)
try:
# Start and wait for server process
except KeyboardInterrupt:
# Ctrl + C pressed
celery_process.terminate()
celery_process.wait()
代码启动了 celery worker,并尝试在捕获到
KeyboardInterrupt 异常时将其热关闭。
初看上去没什么问题。然而实际测试时却发生了十分诡异的事情:按下 Ctrl+C 后,程序 偶尔 会抛出这样的异常:RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>’>。诡异之处有两点:
异常发生的时机有随机性
异常的 traceback 指向 celery 包,也就是说这是在 celery 主进程内部发生的异常
这个结果大大出乎了我的意料。随机性异常是众多最难缠的问题之一,因为这常常意味着并发问题,涉及底层知识,病灶隐蔽,调试难度大,同时没有有效的手段判断问题是否彻底解决(可能只是降低了频率)。
展开全文
相关文章推荐
- 干货 | 如何用 Python 打造一个聊天机器人?【附代码】
- 一个分号引发的思考
- 一个嵌入式初学者引发的思考(jesse谈自己的经验体会)
- mysql中一个普通ERROR 1135 (HY000)错误引发的血案
- elf增加一个可执行段以注入代码的一些思考
- 信号机制的两个思考
- Python通过90行代码搭建一个音乐搜索工具
- 写代码一定要标准,一个String比较引发的血案
- arp协议的混乱引发的思考--一个实例
- 一个VC编译错误引发的对显示类型转换的思考(static_cast、dynamic_cast和const_cast)
- 【案例讨论】从案例引发的对缓存设计的思考,干货讨论,绝对不玩虚的
- 一个类似的python消息响应机制的实现
- 判断一个用户输入的日期是不是闰年. Python 代码
- 一个 11 行 Python 代码实现的神经网络
- 一个事故引发的思考
- SDL入门教程(五):6、对C++异常机制的思考,代码重写
- 一个PV操作题引发的思考,如何看待进程间同步、互斥
- 一个普通ERROR 1135 (HY000)错误引发的血案:
- 一个bug引发的思考 --- ASP.NET页面加载顺序讨论
- Python3中重新加载一个新的更正的代码