簡體   English   中英

非阻塞套接字可以從讀取器/寫入器引發 BlockingIOError 嗎?

[英]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.readsocket.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM