【前言】
前面介紹邏輯和服務,原始碼在後面github給出。
【上回戰況】
上回,主要確定了伺服器的控制邏輯(乙個總程序/執行緒關係圖)。
【最新戰況】
下面,從一些主要邏輯**講解。
在程序池中的子程序中,我使用了epoll_wait在等待請求的到來,如果是外界訊號/來自父程序的資訊(新的連線請求),那就處理/accept連線然後向epoll註冊該套接字。重要部分是,當已連線的請求來時,子程序epoll_wait返回,開始處理事件,怎麼處理呢?我定義了乙個 超級伺服器 (xserver類,這個名稱我從xinetd是inetd的改進版搞來的),它主要是
控制邏輯(程序/執行緒)
和具體服務
的橋梁。如下(從主程序->子程序->子執行緒->xserver解說結構):
主程序邏輯:
templatevoid processpool::run_parent()
/* 有來自外界的訊號 */
else if (sockfd == sig_pipefd[0] && (event[i].events & epollin))
else
continue;
} }
}
主程序主要處理兩個事件。第一,有新的請求就通知其中乙個子程序(通過unix域套接字,之前以建立);第二,接受到外界訊號,處理就ok。
子程序邏輯:
templatevoid processpool::run_child()
/* 來子外界的訊號,如在終端輸入kill -signal pid給此程序時 */
else if (sockfd == sig_pipefd[0] && (event[i].events & epollin))
/* 已經連線的使用者傳送請求的資料到達 */
else if (event[i].events & epollin)
else
continue;
} } .......
}
這就是插入函式的操作,注意,插入任務後會呼叫sem_post傳送乙個訊號,為什麼?因為此程序裡的所有執行緒都在等任務的到來嘛,如下就是每個執行緒執行的函式,整個生命期就是這個函式:
templatevoid threadpool::run(int index)
}
執行緒就是呼叫sem_wait等待,沒有任務是就阻塞,有任務就搶!
注意這裡用 訊號量 、 互斥量並用的好處哦,這樣可以避免無任務時,處理任務的執行緒老是獲得鎖而造成浪費cpu資源,但從另一方面考慮,互斥量是比訊號量快的(詳見《unix環境高階程式設計》p459)。想象一種情況,沒有任務來時,子執行緒老是在加鎖、解鎖,而沒有做半點有用的事。
好的,控制邏輯就是這樣了,注意到上面的request變數嗎,它是模板引數型別,那就是我們需要什麼型別的服務就傳遞什麼引數啦(我這裡傳遞了xserver超級服務類為引數)!剛才我已經說過,xserver是乙個超級服務型別,它是控制邏輯和具體服務的橋梁,我們通過它提供的process函式呼叫開始具體的任務處理,那麼如何實現呢?如下:
int process()}}
這裡同樣忽略細節,注意到,因為這是乙個超級服務類,提供的是所有服務的集合,而具體服務就應該是乙個類,提供明確的服務的類。前面我說過整個專案的通訊是自定義了乙個資料結構確定不同客戶請求的,xserver就是使用標籤來識別具體任務,然後將任務交給具體服務類(分解msgpack資訊包,將明確資訊傳遞給具體類處理)。
【qt伺服器成長狀況】
① 有大腦,也就是控制邏輯啦。
② 有手有腳的哦,因為超級服務類嘛,但卻不能做什麼事哦,沒有工具!!!
【github】
可能沒立刻更新,寫了blog再整理提交^^
伺服器程式設計模型
從執行緒的角度,可以將伺服器程式設計分為兩類 單執行緒和多執行緒。單執行緒模型 乙個程序中只有乙個執行緒,由於只有乙個執行緒,所以要實現高效能,必須與 non blocking i o i o multiplexing 相結合,另外 libevent 本身也是單執行緒的。相對於多執行緒,單執行緒 s...
伺服器程式設計初探
換工作了後,很久沒有來寫點什麼,總感覺時間不夠用。一則工作上的事情比較多 在生活上的時間也比較多。閒話不說,直接談談伺服器程式的設計的幾個部分 1。記憶體分配 記憶體分配對於任何程式都是很重要的,如何分配記憶體,如何減少頻繁的記憶體分配,如何提高記憶體的使用效率,減少記憶體碎片都是需要值得好好研究的...
客戶伺服器程式設計示例
先建立兩個工程server 和client 新增stdafx.h 和winsock2.h 兩個標頭檔案,然後編寫下面的兩段 server.cpp include stdafx.h include winsock2.h include define tchar char pragma comment ...