如今,Python 被認為是一種成熟的編程語言,因其簡單易懂的語法而被數據科學家和人工智慧(AI)工程師廣泛使用。除此之外,編程語言的模糊錯誤通常會讓新程序員揪著頭髮去調試。
在接下來的教程中,我們將討論【Errno 32】break pipe,這是我們在與文件系統交互時經常看到的一個著名的錯誤消息。我們還將了解這種情況的原因,以及避免這種情況並在代碼中修復它的方法。
Python 中「[Errno 32]管道中斷」的原因是什麼?
「管道中斷」通常被認為是IOError(T2 的簡稱】輸入/輸出錯誤)錯誤,發生在 Linux 系統級別。它通常在讀寫文件時引發,或者換句話說,在執行文件輸入/輸出或網路輸入/輸出(通過套接字)時引發。
等效的 Linux 系統錯誤是 EPIPE,摘自 GNU libc 錯誤代碼。
宏:int〔t0〕epipe〔t1〕
「破管子。」沒有來自管道另一端的過程讀數。產生錯誤代碼的庫的每個功能也產生一個信號;如果未被處理或阻止,此信號將終止程序。因此,該程序將永遠不會真正顯示 EPIPE ,直到它處理或阻止 SIGPIPE。****
從上面的陳述,我們可以得出結論:系統發送 SIGPIPE 信號導致【Errno 32】管道中斷錯誤,這是 Linux 的進程間通信機制。
例如,Linux 系統內部使用另一個名為 SIGINT 的信號。在 Linux 中,命令 Ctrl+C 會發出 SIGINT 信號以結束進程,或者我們可以利用殺死命令以達到同樣的效果。
Python 默認不忽略 SIGPIPE 。但是,它會將信號轉換為異常,並在每次收到信號管道時引發錯誤 – IOError: [Errno 32]管道破裂。
當管道導致 Linux 終端時,管道破裂錯誤
每當我們在嘗試將 Python 腳本的輸出傳輸到另一個程序時遇到【Errno 32】管道中斷錯誤,如下例所示:
示例:
$ python file_name.py | head
說明:
管道的上述語法將創建一個向上游發送數據的進程和一個向下游讀取數據的進程。當下游不必讀取上游數據時,它會向上游的進程發送一個 SIGPIPE 信號。
下游什麼時候不用讀取上游數據?讓我們用一個例子來理解這一點。示例中的頭命令只需要讀取足夠多的行就可以告訴上游我們不再需要讀取它,它會向上游的進程發送 SIGPIPE 信號。
每當上游進程是 Python 程序時,就會出現類似IOError:【Errno 32】管道中斷的錯誤。
如何避免管道中斷錯誤?
如果我們不關心正確捕獲 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 手冊,以警告不要進行這種 SIGPIPE 處理。
正確捕捉 IOError 以避免管道破裂錯誤
由於管道中斷錯誤是一個 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 塊,以便捕獲引發的異常並處理它。
多進程程序中管道中斷錯誤的一種可能解決方案
在利用工作進程來加速處理和利用多核處理器的程序中,我們可以嘗試減少工作進程的數量來檢查錯誤是否仍然存在。
當試圖控制系統資源或許可權以便寫入磁碟時,大量工作進程可能會相互衝突。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/301020.html