IOError: [Errno 32] Broken pipe 错误分析

一、概述

Broken pipe 本质是 IOError 错误,是 Linux 系统层面的机制导致,一般发生在读写文件IO和网络Socket IO的时候。

对应的 Linux 系统错误是 EPIPE,摘自【参考2】的一段话:

'''
Macro: int EPIPE “Broken pipe.” 
There is no process reading from the other end of a pipe. 
Every library function that returns this error code also generates a SIGPIPE signal; 
this signal terminates the program if not handled or blocked. 
Thus, your program will never actually see EPIPE unless it has handled or blocked SIGPIPE.
'''

从这段话,我们可以知道这个错误是由系统 SIGPIPE 信号引起的,信号是 Linux 的一种进程间通信的机制,例如 ctrl+c 就会发送 SIGINT 信号来结束进程,或者使用 kill 命令。

$ kill <pid>

那么 SIGPIPE 信号是由什么来引发的呢?Linux 系统中还有个常见的 Pipe 管道机制,多个命令的组合就会使用到管道。

python <filename>.py | head

管道存在上游发送数据的进程,下游读取数据的进程,在下游不再需要读取上游数据的时候,就会发送 SIGPIPE 信号给上游进程。

什么时候会出现下游不再需要读取上游数据了呢?例如示例中的 head 命令,只需要读够足够的行数,就可以告诉上游我已经不需要再读取了,就会发送 SIGPIPE 信号给上游进程。

当这个上游进程是 Python 程序的时候,就会出现 IOError: [Errno 32] Broken pipe 这样的错误。

原因是:python将这种管道截取的操作当成是一种输出异常,导致异常退出。

解决方式,用try ... except Exception捕获异常即可。

二、解决方法

# 方法1:捕获异常

import sys, errno
try:
    ### IO operation ###
except IOError as e:
    if e.errno == errno.EPIPE:
        ### Handle error ###

# 方法2:忽略信号
from signal import signal, SIGPIPE, SIG_DFL, SIG_IGN
signal(SIGPIPE, SIG_IGN)

# 恢复默认信号行为的方法
# signal(SIGPIPE, SIG_DFL)

 

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值