如今,Python被认为是一种成熟的编程语言,因其简单和易于阅读的语法,广受数据科学家和人工智能(AI)工程师的欢迎。除此之外,编程语言的模糊错误通常让新程序员为了调试而束手无策。

在下面的教程中,我们将讨论经常在与文件系统交互时看到的著名错误消息[Errno 32] Broken pipe。我们还将了解这个错误的原因,以及如何避免它并在代码中修复它。

什么引起了Python中的"[Errno 32] Broken pipe"错误?

"Broken pipe"通常被认为是IOError(输入/输出错误)错误,发生在Linux系统级别。通常在读写文件或者用其他术语说是执行文件的输入/输出或网络的输入/输出(通过套接字)时引发此错误。

等效的Linux系统错误是EPIPE,摘自GNU libc错误代码

宏:int EPIPE

"Broken pipe." 没有任何进程从管道的另一端读取。库的每个引发错误代码的函数也会产生一个SIGPIPE信号;如果不处理或阻止该信号,该信号将终止程序。因此,除非已处理或阻止SIGPIPE,否则程序实际上永远不会显示EPIPE

从上述说明中,我们可以得出结论,系统发送SIGPIPE信号导致[Errno 32] Broken pipe错误,这是Linux的进程间通信机制。

例如,Linux系统内部使用另一个叫做SIGINT的信号。在Linux中,Ctrl+C命令将发送SIGINT信号以结束进程,或者我们可以使用kill命令来实现相同的效果。

Python默认不会忽略SIGPIPE。但是,它将信号转换为异常,并在接收到SIGPIPE时引发错误- IOError: [Errno 32] Broken pipe

在Linux终端中使用管道时出现"Broken Pipe"错误

每当我们尝试将Python脚本的输出通过管道传递给另一个程序时,都会遇到[Errno 32] Broken pipe错误,例如在以下示例中所示:

示例:

$ python file_name.py | head  

说明:

上面的管道语法会创建一个向上游发送数据的进程,以及一个向下游读取数据的进程。当下游不需要读取上游数据时,它将向上游的进程发送一个SIGPIPE信号。

下游何时不需要读取上游数据?让我们通过一个示例来理解。在示例中,head命令只需要读取足够多的行以告知上游不再需要读取它,然后将SIGPIPE信号发送给上游进程。

每当上游进程是Python程序时,就会发生像IOError: [Errno 32] Broken pipe的错误。

如何避免"Broken Pipe"错误?

如果我们不关心正确捕获SIGPIPE并需要快速运行代码,可以将以下代码段插入到Python程序的顶部。

语法:

from signal import signal, SIGPIPE, SIG_DFL   
#Ignore SIG_PIPE and don't throw exceptions on it... (http://docs.python.org/library/signal.html)  
signal(SIGPIPE,SIG_DFL)   

说明:

在上面的代码段中,我们将SIGPIPE信号重定向到默认的SIG_DFL,系统通常会忽略这个信号。

但是,建议谨慎使用Python手册上的关于信号库的警告。

适当捕获IOError以避免"Broken Pipe"错误

由于"Broken Pipe"错误是IOError错误,我们可以放置一个try/catch块来捕获它,如下面的代码段所示:

语法:

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

说明:

在上面的代码段中,我们导入了sys和errno模块,并放置了try/catch块来捕获引发的异常并处理它。

解决多进程程序中的"Broken Pipe"错误的可能方法

在利用工作进程加速处理和利用多核CPU的程序中,我们可以尝试减少工作进程的数量,以查看错误是否仍然存在。

大量的工作进程可能会在尝试控制系统资源或磁盘写入权限时发生冲突。

标签: Tkinter教程, Tkinter安装, Tkinter库, Tkinter入门, Tkinter学习, Tkinter入门教程, Tkinter, Tkinter进阶, Tkinter指南, Tkinter学习指南, Tkinter进阶教程, Tkinter编程