自带的 print 函数居然会报错?(上)

简介: 最近用 Python 写了几个简单的脚本来处理一些数据,因为只是简单功能所以我就直接使用 print 来打印日志。

前言


最近用 Python 写了几个简单的脚本来处理一些数据,因为只是简单功能所以我就直接使用 print 来打印日志。


任务运行时偶尔会出现一些异常:


网络异常,图片无法展示
|


因为我在不同地方都有打印日志,导致每次报错的地方都不太一样,从而导致程序运行结果非常诡异;有时候是这段代码没有运行,下一次就可能是另外一段代码没有触发。


虽说当时有注意到 Broken pipe 这个关键异常,但没有特别在意,因为代码中也有一些发送 http 请求的地方,一直以为是网络 IO 出现了问题,压根没往 print 这个最基本的打印函数上思考🤔。


直到这个问题反复出现我才认真看了这个异常,定睛一看 print 不也是 IO 操作嘛,难道真的是自带的  print 函数都出问题了?


但在本地、测试环境我运行无数次也没能发现异常;于是我找运维拿到了线上的运行方式。


原来为了方便维护大家提交上来的脚本任务,运维自己有维护一个统一的脚本,在这个脚本中使用:


cmd = 'python /xxx/test.py'
os.popen(cmd)


来触发任务,这也是与我在本地、开发环境的唯一区别。


popen 原理


为此我在开发环境模拟出了异常:


test.py:


import time
if __name__ == '__main__':
    time.sleep(20)
    print '1000'*1024


task.py:


import os
import time
if __name__ == '__main__':
    start = int(time.time())
    cmd = 'python test.py'
    os.popen(cmd)
    end = int(time.time())
    print 'end****{}s'.format(end-start)


运行:


python task.py


等待 20s 必然会复现这个异常:


Traceback (most recent call last):
  File "test.py", line 4, in <module>
    print '1000'*1024
IOError: [Errno 32] Broken pipe


为什么会出现这个异常呢?


首先得了解 os.popen(command[, mode[, bufsize]]) 这个函数的运行原理。


网络异常,图片无法展示
|


根据官方文档的解释,该函数会执行 fork 一个子进程执行 command 这个命令,同时将子进程的标准输出通过管道连接到父进程;


也就该方法返回的文件描述符。


这里画个图能更好地理解其中的原理:


网络异常,图片无法展示
|

在这里的使用场景中并没有获取 popen() 的返回值,所以 command 的执行本质上是异步的;


也就是说当 task.py 执行完毕后会自动关闭读取端的管道。


网络异常,图片无法展示
|
如图所示,关闭之后子进程会向 pipe 中输出   print '1000'*1024,由于这里输出的内容较多会一下子填满管道的缓冲区;


于是写入端会收到 SIGPIPE 信号,从而导致 Broken pipe 的异常。


从维基百科中我们也可以看出这个异常产生的一些条件:


网络异常,图片无法展示
|


其中也提到了 SIGPIPE 信号。


相关文章
|
人工智能 编解码
ReCamMaster:视频运镜AI革命!单镜头秒变多机位,AI重渲染颠覆创作
ReCamMaster 是由浙江大学与快手科技联合推出的视频重渲染框架,能够根据用户指定的相机轨迹重新生成视频内容,广泛应用于视频创作、后期制作、教育等领域,提升创作自由度和质量。
966 0
|
存储 人工智能 算法
《探秘AI绿色计算:降低人工智能硬件能耗的热点技术》
在人工智能快速发展的背景下,硬件能耗问题日益突出。为实现绿色计算,降低能耗成为关键课题。新型硬件架构如CRAM、自旋电子器件和量子计算硬件,以及优化的低功耗芯片设计、3D集成技术和液冷散热技术等,正崭露头角。同时,硬件与软件协同优化,通过模型压缩、算法适配等手段,进一步提升能效。这些技术将推动AI向更绿色、高效的方向发展,助力应对全球气候变化。
718 19
|
缓存 自然语言处理 搜索推荐
深入优化基于DeepSeek的智能客服系统:从基础到高级
本文在上一篇构建的DeepSeek智能客服系统基础上,深入探讨了性能优化、用户体验提升和高级功能集成的方法。通过缓存机制、异步处理优化性能;利用情感分析、个性化回答提升用户体验;引入语音识别、知识图谱等高级功能增强智能化水平。结合具体案例与代码示例,帮助开发者打造更高效、智能的客服系统。
|
开发工具 数据安全/隐私保护 git
GPG 101
本文介绍了GPG(GnuPG)的基本使用方法,GPG是OpenPGP标准的完整免费实现,支持数据加密和签名。文章涵盖GPG的基础概念、安装、密钥生成与管理、导出与导入、签名与验证、加密与解密以及Git配置等内容。特别提醒不要上传任何信息到公共密钥服务器,以免造成安全隐患。更多详细内容请参考我的博客:[gpg-101](https://blog.timerring.com/posts/gpg-101)。
547 6
|
测试技术
新年第一弹!全新的过程奖励模型PRM开源
新年第一弹!全新的过程奖励模型PRM开源
|
消息中间件 人工智能 Kubernetes
解密开源Serverless容器框架:事件驱动篇
Knative是一款基于Kubernetes的开源Serverless框架,提供了云原生、跨平台的Serverless编排标准。作为Serverless中必不可少的事件驱动能力,Knative Eventing提供了云原生的事件驱动能力。
|
云安全 人工智能 自然语言处理
|
机器学习/深度学习 数据采集 算法
【数据分享】简化的评分卡、Smote采样和随机森林的信贷违约预测
【数据分享】简化的评分卡、Smote采样和随机森林的信贷违约预测
|
监控 网络协议 Linux
Linux I/O多路复用深入解析:从select到epoll的演进之路
Linux I/O多路复用深入解析:从select到epoll的演进之路
834 0
|
SQL 缓存 网络协议
利用QT实现多平台数据互通
利用QT实现多平台数据互通
614 0