![](/img/trans.png)
[英]Force a non-blocking UDP socket to raise BlockingIOError on sendto
[英]Can a non-blocking socket raise BlockingIOError from a reader/writer?
sock.recvfrom
可以從讀者sock.recvfrom
引發BlockingIOError
嗎? 比如下面
sock.setblocking(False)
def reader()
try:
(data, addr) = sock.recvfrom(512)
except BlockingIOError:
# Can this ever be raised?
loop.add_reader(sock.fileno(), reader)
類似地, sock.send
是否可以從作者sock.send
引發BlockingIOError
?
sock.setblocking(False)
def writer()
try:
bytes_sent = sock.send(data)
except BlockingIOError:
# Can this ever be raised?
loop.add_writer(sock.fileno(), writer)
我已經嘗試發送/接收相當多的數據,但到目前為止從未發生過。 從邏輯上講,它真的永遠不會發生嗎? 如果可以,在什么情況下發生?
[
BlockingIOError
in a asyncio reader] 從邏輯上講,真的永遠不會發生嗎? 如果可以的話,是在什么情況下發生的?
這個問題的答案幾乎肯定取決於系統。 Python 本身不提供任何保證: os.read
和socket.recv
類的函數只檢查底層系統調用返回的值,如果它指示錯誤,繼續將系統提供的錯誤轉換為蟒蛇異常。
因此,問題歸結為如果前面的輪詢/選擇表明它是可讀的(以及寫入的等效項),那么從套接字讀取是否會因EAGAIN
或等效項而失敗。 雖然這聽起來像是一種異常情況,但select(2)
手冊頁在 BUGS 下明確警告了它:
在 Linux 下,
select()
可能會將套接字文件描述符報告為“ready for reading”,但隨后的讀取會阻塞。 例如,當數據已到達但檢查時校驗和錯誤並被丟棄時,可能會發生這種情況。 可能還有其他情況,其中文件描述符被虛假地報告為就緒。 因此,在不應阻塞的套接字上使用O_NONBLOCK
可能更安全。
對於非阻塞套接字,應該將“盡管如此,隨后的讀取阻塞”讀作“盡管如此,隨后的讀取失敗並使用EAGAIN
”,並且警告適用於這個問題。 這個問題也不是特定於select()
; poll(2)
手冊頁還在其 BUGS 部分提到了虛假喚醒,有關詳細信息,請參閱select(2)
手冊。
換句話說,可移植代碼不應依賴於從不會引發BlockingIOError
“可讀”套接字讀取。 Asyncio 不依賴它:它通過簡單地不完成 future來對EAGAIN
做出反應,從而重新掛起等待讀取的協程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.