天天看點

python 管道 非阻塞_Python非阻塞網絡通信Howto

在Python中,你使用socket.setblocking(0)使它無阻塞。在C中,它更複雜,(一方面,你需要在BSD風格O_NONBLOCK和幾乎不可區分的Posix風味O_NDELAY之間進行選擇,這完全不同于TCP_NODELAY),但它是完全相同的想法。你在建立套接字之後,但在使用之前這樣做。 (實際上,如果你堅果,你可以來回切換。)

主要的機械差異是send,recv,connect和accept可以傳回而沒有做任何事情。你有(當然)一些選擇。你可以檢查傳回碼和錯誤代碼,一般驅使自己瘋了。如果你不相信我,試試它。你的應用程式将增長,bug和吸CPU。是以,讓我們跳過腦死亡的解決方案,make it right。

使用select。

在C中,select編碼相當複雜。 在Python中,它很簡單,而且它足夠接近C版本,如果你了解在Python中的select,你會有很少的麻煩在C

ready_to_read, ready_to_write, in_error = \

select.select(

potential_readers,

potential_writers,

potential_errs,

timeout)

你傳遞選擇三個清單:第一個包含您可能想要嘗試閱讀的所有套接字;第二個所有的套接字你可能想嘗試寫入,最後一個(通常留白)那些你想檢查錯誤。你應該注意一個套接字可以進入多個清單。選擇調用正在阻塞,但您可以給它一個逾時。這通常是一個明智的事情 - 給它一個很長的逾時(說一分鐘),除非你有很好的理由,否則。

作為回報,你會得到三個清單。它們包含實際可讀,可寫和錯誤的套接字。這些清單中的每一個都是傳入的相應清單的子集(可能為空)。

如果一個套接字在輸出可讀清單中,您可以像我們一直在這個業務中那樣接近,那麼該套接字上的recv會傳回一些東西。可寫清單的想法相同。你可以發送東西。也許不是你想要的,但有些事情比沒有好。 (實際上,任何合理健康的套接字将傳回為可寫 - 它隻是意味着出站網絡緩沖區空間可用。)

如果你有一個“伺服器”套接字,将其放在potential_readers清單中。如果它出現在可讀清單中,你的接受(幾乎肯定)工作。如果您建立了一個新的套接字以連接配接到其他人,請将其放在potential_writers清單中。如果它顯示在可寫的清單中,你有一個體面的機會,它已經連接配接。

一個非常讨厭的問題與選擇:如果在那些輸入清單中的插座是一個死了一個讨厭的死亡,選擇将失敗。然後,你需要循環通過所有這些清單中的每個單獨的套接字,并做一個select([sock],[],[],0),直到你找到了壞的。逾時為0意味着它不會需要很長時間,但它是醜陋的。

實際上,即使使用阻塞套接字,選擇也可以友善。這是一種确定是否阻塞的方法 - 當緩沖區中有某些東西時,套接字傳回可讀。然而,這仍然不能幫助确定另一端是完成還是隻忙于其他事情的問題。