C 實現基於單執行緒單客戶模型的echo程式

2021-07-04 10:32:56 字數 2420 閱讀 1048

乙個客戶乙個子執行緒,也是阻塞式網路程式設計,它的初始化要比乙個客戶乙個程序模型開銷要小;但是仍適合於長連線,不適合短連線、併發數不大的情況,尤其不適合pthread_create()的開銷大於本身服務的情況;

程式設計模型

;(注:fork子程序是拷貝父程序的位址空間,但是寫內容時才會申請對應的記憶體,也就是寫時複製的思想,簡稱cow,而主程序建立的子執行緒仍與主程序位於同乙個位址空間)

(3)併發伺服器2,類似於乙個客戶乙個程序的併發伺服器2,只不過預先派生一定數量為n的子執行緒,子執行緒也同時也監聽,當各個客戶連線到達時,這些子執行緒就能夠立即為它們服務,無需建立的開銷;但是如果連線數等於n時(注,父程序不參與服務),此時子程序將會被使用完,新到的連線需等到乙個子執行緒可用,如果連線數還未到達listen呼叫的backlog數,三次握手已經完成,但是客戶端無法被服務,需要等到子執行緒執行到accept返回才可被服務,客戶端將會明顯察覺到伺服器在響應時間上的惡化,雖然客戶端的connect會立即返回,但是第乙個請求在一段時間之後才會被伺服器處理;

(4)併發伺服器3,它與併發伺服器2類似,只不過在accpet加上互斥量,使得accept這段**成為臨界區;由原先的accept爭用變成了鎖爭用,最終只有乙個程序阻塞在accept上,也就是臨界區只有乙個執行緒阻塞在accept上;

(5)併發伺服器4,它使用分發機制;子執行緒不進行accept呼叫,統一由父程序accept然後將連線描述符傳遞(共享)給對應的子執行緒,然後由子執行緒為客戶端服務,父執行緒可使用普通的輪轉法來選擇子執行緒服務;

(1)tcp是乙個全雙工的協議,同時支援read()和write();而阻塞式網路程式設計中,伺服器主程序通常阻塞在accept上,而由子執行緒具體負責與具體的客戶端通訊,客戶端通常阻塞在read系統呼叫上,等待客戶端發來的命令;這樣就需要服務端和客戶端的程式設計需要相互配合起來;假設客戶端程序由於錯誤的程式邏輯阻塞在read上,伺服器端也阻塞在read上,那麼雙方出現了通訊死鎖的情況;

(2)某些客戶端繼續阻塞的讀連線資料,又需要讀鍵盤輸入,如果阻塞的讀連線資料,那麼是無法從鍵盤讀輸入的;伺服器為每乙個連線準備乙個執行緒,乙個連線將會獨佔乙個執行緒,伺服器的開銷較大;如果客戶端不主動退出,將會耗費伺服器端的資源;

(3)適合計算響應的工作量大於本身建立開銷的服務;

(1)下面是針對併發伺服器1的具體實現;

(3)伺服器不主動斷開連線,而由客戶端從鍵盤獲得eof或客戶端退出後,伺服器也將會退出;

tcpserver服務端實現

tcpserver介面

class tcpserver final  

;

說明幾點:

(1)與乙個客戶乙個程序介面類似;不同點:只不過少了子程序終止的訊號處理程式,以及缺少析構函式,因為只有乙個主程序,沒有孩子執行緒產生;這裡也並沒有處理終止執行緒的pthread_join方法;可以使用乙個列表將所有的pthread蒐集起來,最後tcpserver析構的時候來使用pthread_join終止每乙個子執行緒;

(2)_servicecount將表示tcpserver服務的次數,而不是fork後的子程序服務次數;(注:fork子程序拷貝父程序的位址空間,但是寫時才會申請對應的記憶體,也就是寫時複製的思想,簡稱cow,而主程序建立的子執行緒仍與主程序位於同乙個位址空間)

伺服器啟動

void tcpserver::start()  

else

} }

說明幾點:

(1) ::pthread_create建立執行緒,並將連線描述符,通過引數傳入;

(2)與乙個客戶乙個程序不同的是,並不需要在建立執行緒後關閉connd,因為執行緒與主程序共享,並不像fork()將增加connd的引用計數;

服務實現

void* tcpserver::_service(void* arg)  

sockets::close(connfd);

return null;

}

說明幾點:

(1)服務內容,主要就是將從客戶端讀取的內容直接**至對應的連線,由於read和write屬於阻塞操作,可以保證接收到的位元組全部**至客戶端;

(3)最後當read到0,說明客戶端已經斷開連線;伺服器執行::exit(0)將會使核心傳送fin報文,伺服器端將會從close_wait變為last_ack狀態;

tcpclient客戶端實現

與乙個客戶乙個程序的tcpclient客戶端一樣,不再贅述;

NIO實現Reactor單執行緒模型

寫這個模型需要提前了解selector以及channel,之前記錄過filechannel,除此之外還有以下幾種channel serversocketchannel 用於監聽新的tcp連線的通道,負責讀取 響應,通常用於服務端的實現。socketchannel 用於發起tcp連線,讀寫網路中的資料...

C 簡單執行緒池實現

執行緒池,簡單來說就是有一堆已經建立好的執行緒 最大數目一定 初始時他們都處於空閒狀態,當有新的任務進來,從執行緒池中取出乙個空閒的執行緒處理任務,然後當任務處理完成之後,該執行緒被重新放回到執行緒池中,供其他的任務使用,當執行緒池中的執行緒都在處理任務時,就沒有空閒執行緒供使用,此時,若有新的任務...

c 簡單執行緒池實現

boost threadpool參考 執行緒池,簡單來說就是有一堆已經建立好的執行緒 最大數目一定 初始時他們都處於空閒狀態,當有新的任務進來,從執行緒池中取出乙個空閒的執行緒處理任務,然後當任務處理完成之後,該執行緒被重新放回到執行緒池中,供其他的任務使用,當執行緒池中的執行緒都在處理任務時,就沒...