最近做一個套接字程式設計的應用,伺服器使用Unix。
對于套接字異步的選擇,一般有兩種模式,一種是對每個新到來的連接配接都建立一個線程(pthread),可以使用線程池對其進行管理;
另外一種是使用單程序下的異步I/O,通過函數select()來實作;
select()函數可以完成非阻塞方式工作的程式,它能夠監視我們需要監視的檔案描述符的變化情況——讀寫或是異常
這裡的非阻塞是指程序或線程執行此函數時不必非要等待事件的發生,一旦執行肯定傳回,以傳回值的不同來反映函數的執行情況
如果事件發生則與阻塞方式相同;若事件沒有發生則傳回一個代碼來告知事件未發生,而程序或線程繼續執行)
而至于這兩者那一種效率更高就比較模糊了。
下面是IBM關于異步伺服器的觀點:
異步伺服器
另一種稱為 異步 或 非阻塞 socket 的技術甚至可能比線程化或分支方法更有效率。異步程式設計背後的概念是将執行保持在單個線程内,但是要輪詢每個打開的 socket,以确定它是否有更多的資料在等待讀入或寫出。然而,非阻塞 socket 實際上僅對受 I/O 限制的程序有用。我們使用
sleep()
建立的受 CPU 限制的伺服器模拟就在一定程度上遺漏了這個要點。此外,非阻塞 socket 對 TCP 連接配接比對 UDP 連接配接更有意義,因為前者保持一個可能仍然具有未決資料的打開連接配接。
概而言之,異步對等方(客戶機 或 伺服器)的結構是一個輪詢循環 ―― 通常使用函數
select()
或它的某個進階包裝,比如 Python 的
asyncore
。在每次經過循環時,您都要檢查所有打開的 socket,以确定哪些目前是可讀的,以及哪些目前是可寫的。這檢查起來很快,并且您可以簡單地忽略目前沒有為 I/O 操作做好準備的任何 socket。這種 socket 程式設計風格避免了與線程或程序相關聯的任何開銷。
至此,關于兩者的選擇也比較清楚了。