方式二:只有每出現乙個新的連線時,我們才隨新連線建立乙個新的結構體空間,將它與新的客戶端socket繫結在一起,只有當客戶端socket關閉時才將它與客戶端物件一起銷毀;
方式三:建立一定量的結構體空間,並將其統一放入乙個空閒佇列,不管何時執行wsasend和wsarecv,都先從空閒佇列裡取乙個結構體空間來用,用完後,將其放回空閒佇列。
從執行的效率及實現的便捷性方面考慮,建議採用方式3的形式管理這些空閒結構體空間。採用方式3的難點在於,到底建立多少個結構體空間才是比較合適的?這可能取決於你在自己伺服器上作的完成埠的處理效率,如果完成埠的處理效率比較高,那麼需要的佇列長度可能就比較小,如果完成埠的處理效率低,那麼佇列長度就要大一點。
下面說說「連線池」。我們知道,使用傳統的accept接收客戶端的乙個連線後,此函式會返回乙個建立成功的客戶端socket,也就是說,此函式自己完成了socket的建立工作。非常好的是,windows給我們提供了另乙個函式,允許我們在接受連線之前就事先建立乙個socket,使之於接受的連線相關聯,這個函式就是acceptex,在acceptex的引數中,socket型別的引數值是我們事先用socket函式建立完成的乙個socket,在呼叫acceptex時,把這個已經建立好的socket傳給acceptex。說到這裡,明白的人可能已經偷笑了--既然這樣,那豈不是允許我們在接受連線之前就建立好一大堆的socket等著acceptex來用嗎?這就省去了臨時建立乙個socket的系統開銷呀?呵呵,事實確實如此。在實際操作中,我們可以事先建立好一大堆的socket,然後接受客戶端連線的函式使用acceptex。這一大堆的socket,我們可以形象地稱之為「socket連線池」(當然,也許在更多的場合,我們聽到的是「資料庫連線池」的概念),這個名字是我自己取的,聽著覺得不舒服的兄弟,乾脆就叫它「socket池」吧,哈哈。
執行緒池的概念,相信作過多執行緒的朋友都會有所耳聞。在此處的文字中,就不對它再多加介紹了,感興趣的朋友可以自己去google一下。我這裡說的執行緒池,不僅僅指由完成埠自己負責維護的那個工作者執行緒池,還指我們建立在完成埠模型基礎之上的執行緒池。這個執行緒池裡又具體分為執行邏輯執行緒池和傳送執行緒池。當然,也有人建議執行邏輯執行緒只要一條就行了,沒必要用多條,而且同步會非常麻煩。我贊同這種說法以,但前提是,這樣的設計,要求你對伺服器功能的劃分要相當合理,否則會讓這一條執行緒累得夠嗆。
未完待續。
完成埠之效能優化 1
方式二 只有每出現乙個新的連線時,我們才隨新連線建立乙個新的結構體空間,將它與新的客戶端socket繫結在一起,只有當客戶端socket關閉時才將它與客戶端物件一起銷毀 方式三 建立一定量的結構體空間,並將其統一放入乙個空閒佇列,不管何時執行wsasend和wsarecv,都先從空閒佇列裡取乙個結構...
完成埠之效能優化 1
方式二 只有每出現乙個新的連線時,我們才隨新連線建立乙個新的結構體空間,將它與新的客戶端socket繫結在一起,只有當客戶端socket關閉時才將它與客戶端物件一起銷毀 方式三 建立一定量的結構體空間,並將其統一放入乙個空閒佇列,不管何時執行wsasend和wsarecv,都先從空閒佇列裡取乙個結構...
完成埠之效能優化 1
方式二 只有每出現乙個新的連線時,我們才隨新連線建立乙個新的結構體空間,將它與新的客戶端socket繫結在一起,只有當客戶端socket關閉時才將它與客戶端物件一起銷毀 方式三 建立一定量的結構體空間,並將其統一放入乙個空閒佇列,不管何時執行wsasend和wsarecv,都先從空閒佇列裡取乙個結構...