天天看點

多路複用

多路複用

  在用戶端/伺服器模型中,伺服器端需要同時處理多個用戶端的連接配接請求,此時就需要使用多路複用。

  實作多路複用最簡單的方法是采用非阻塞的方式套接字,伺服器端不斷的查詢每一個套接字的狀态,如果有資料到達則讀出資料,如果沒有資料到達則檢視下一個套接字。這種方法雖然簡單,但是輪詢過程中浪費了大量的CPU時間,效率非常的低。

  另一種方法是伺服器程序并不主動的詢問套接字的狀态,而是向系統登記希望堅實的套接字,然後阻塞。當套接字上有事件發生時(如有資料到達),系統通知伺服器程序告知那個套接字上發生了什麼事件,伺服器程序查詢對應的套接字,并進行處理。在這種工作方式下,套接字上沒有事件發生時,伺服器程序不會去查詢套接字的狀态,進而不會浪費CPU的時間,提高了效率。

  使用函數select可以實作第二種多路複用。

  int select(int n, fd_set *readfds, fd_set *writefds, fd_set *expectfds, struct timeval *timeout);

  參數n是要監視的檔案描述符數,要監視的檔案描述符值為0~n-1。

  參數readfds制定需要監視的可讀檔案描述符集合,當這個集合中的一個描述符上有資料到達的時候,系統将通知調用select函數的程式。

  參數writefds指定需要監視的可寫檔案描述符集合,當這個集合中的一個描述符可以發送資料時,程式将得到通知。

  參數expectfds指定需要監視的異常檔案描述符集合,當有一個描述符發生異常的時候,程式将得到通知。

  參數timeout設定阻塞的時間。

  系統為檔案描述符集合提供了一系列的操作宏:

FD_CLR(int fd,fd_set *set) 将檔案描述符fd從檔案描述符集合set中删除

FD_ISSET(int fd,fd_set *set) 測試fd是否在set中

FD_SET(int fd,fd_set *set) 在檔案描述符集合set中增加檔案描述符fd

FD_ZERO(fd_set *set)

  

伺服器端

   伺服器程式用fork函數來處理多個用戶端,但是在資料庫應用程式中,這可能不是最佳的解決辦法。因為伺服器将程式可能會相當大,而且在資料庫通路方面還存在着多個伺服器副本的協調問題。

  是以我們需要一個辦法支援讓單個伺服器程序在不阻塞,不等待客戶請求帶大的前提下處理多個客戶。是以選擇select。程式如下

繼續閱讀