日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较

發(fā)布時(shí)間:2023/11/27 生活经验 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? ? 經(jīng)過之前四篇博文的介紹,可以大致清楚各種模型的編程步驟?,F(xiàn)在我們來回顧下各種模型(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)

模型編程步驟對(duì)比

? ? ? ? 《樸素、Select、Poll和Epoll網(wǎng)絡(luò)編程模型實(shí)現(xiàn)和分析——樸素模型》中介紹的是最基本的網(wǎng)絡(luò)編程模型,我們使用單線程去實(shí)現(xiàn),它的步驟很簡(jiǎn)單

?

? ? ? ? 如同這幅流程圖,它簡(jiǎn)單到非常單薄。這個(gè)模型暴露出來的問題是在一個(gè)線程中,它一次只能處理一個(gè)請(qǐng)求。當(dāng)然我們可以通過多線程或者多進(jìn)程的模式對(duì)該模型進(jìn)行改進(jìn):主線程監(jiān)聽接入socket請(qǐng)求,將其保存到一段空間中。其他線程從該段空間中獲取socket并處理。但是這種改善不是從網(wǎng)絡(luò)編程模型的角度出發(fā)的,而是多線程/多進(jìn)程的一種應(yīng)用,這種應(yīng)用也可以用于之后幾個(gè)模型。所以我們暫且拋開這種優(yōu)化來討論。

? ? ? ? 《樸素、Select、Poll和Epoll網(wǎng)絡(luò)編程模型實(shí)現(xiàn)和分析——Select模型》解決了樸素模型同步的執(zhí)行的問題,而且還解決了一次只能處理一個(gè)請(qǐng)求的問題。


? ? ? ? 可以見得這種模型稍微厚實(shí)了一點(diǎn),但是它也有一個(gè)問題:最多只能同時(shí)處理1024個(gè)請(qǐng)求。致命的是這種限制是在內(nèi)核代碼級(jí)別的(詳見之前文章的分析)。為了解決這個(gè)問題于是就有了poll模型。

? ? ? ? 《樸素、Select、Poll和Epoll網(wǎng)絡(luò)編程模型實(shí)現(xiàn)和分析——Poll模型》中介紹的Poll模型結(jié)構(gòu)和Select模型是非常相似的,但是它不再依賴于結(jié)構(gòu)體的位數(shù)來限制最多處理的socket數(shù),而是采用一個(gè)數(shù)組去保存數(shù)據(jù)。


? ? ? ? poll模型的問題是其效率隨著同時(shí)連接的socket數(shù)而下降。因?yàn)樗蚐elect模型有著相同的缺陷——每次只是知道有事件發(fā)生,但是不知道是哪個(gè)socket有事件發(fā)生,于是需要遍歷所有的socket。這樣socket如果越來越多,它的效率自然會(huì)下降。為了解決這個(gè)問題,于是有了Epoll模型。

? ? ? ? 《樸素、Select、Poll和Epoll網(wǎng)絡(luò)編程模型實(shí)現(xiàn)和分析——Epoll模型》算是目前最優(yōu)秀的解決多連接的模型。但是它也是最復(fù)雜的模型。


模型效率對(duì)比

? ? ? ? 首先明確一個(gè)立場(chǎng),沒有實(shí)際測(cè)試數(shù)據(jù)的對(duì)比都是空談。網(wǎng)上一般充斥的一種觀點(diǎn)就是EPOLL模型效率最好,Poll和Select模型相當(dāng),樸素模型最差。但是這個(gè)觀點(diǎn)是錯(cuò)誤的。因?yàn)椴煌哪P驮诓煌氖褂脠?chǎng)景下有著不同的效率。

? ? ? ? 比如,在我們之前測(cè)試的場(chǎng)景下。樸素模型的平均處理能力大概是15000次/秒,Select的平均處理能力是7000次/秒,Poll的平均處理能力是7500次/秒,Epoll的平均處理能力是11000次/秒。為什么樸素模型的處理能力是最高的?因?yàn)槲覀冞@個(gè)是一個(gè)典型的短連接、一次性交互的場(chǎng)景,這種場(chǎng)景下如果得到一個(gè)請(qǐng)求馬上去讀和寫,而不經(jīng)過其他復(fù)雜的過程,自然是最快的。Poll模型和Select模型能力相當(dāng)。Epoll是對(duì)Poll模型的優(yōu)化,所以它的效率比Select和Poll要好一些。

? ? ? ? 我們使用valgrind對(duì)上述四種模型的執(zhí)行情況進(jìn)行分析。

? ? ? ? 首先我們看樸素模型


? ? ? ? 樸素模型的main函數(shù)自身(即刨除下面列出的函數(shù)的其他執(zhí)行時(shí)間)的執(zhí)行時(shí)間占比是非常小的(5.45%),其主要的耗時(shí)操作是讀和寫操作(server_write占38.94%,server_read占27.64%)。

? ? ? ? ?我們?cè)倏聪滦实诙腅poll模型


? ? ? ? 可見Epoll模型中,server_write操作耗時(shí)占比最高(29.32%),其次是main函數(shù)自身耗時(shí)占(25.7%),再次是server_read(22.48%)。

? ? ? ? 再看下效率倒數(shù)第二的Poll模型


? ? ? ? Poll模型中main函數(shù)自身耗時(shí)占比最高(46.93%),其次是server_write(21.44%),再次是server_read(16.44%)。我們看到main函數(shù)自身耗時(shí)提高非常多。

? ? ? ? 最后我們看看效率最低的Select模型


? ? ? ? Select模型中,main函數(shù)自身耗時(shí)占比最多(97.99%),其次是server_write(0,83%),再次是server_read(0.64%)。那么main函數(shù)中什么是最耗時(shí)的呢?我對(duì)Select模型源碼進(jìn)行了細(xì)分,將之前循環(huán)遍歷各個(gè)Socket的邏輯提煉出來

void deal_socket(int index, int listen_sock, fd_set* active_fd_set, fd_set* read_fd_set) {if (listen_sock == index) {/* Connection request on original socket. */int new_sock;new_sock = accept(listen_sock, NULL, NULL);if (new_sock < 0) {perror("accept error");exit(EXIT_FAILURE);}request_add(1);FD_SET(new_sock, active_fd_set);} else {if (0 == server_read(index)) {server_write(index);}close(index);FD_CLR(index, active_fd_set);}
}void deal_request(int listen_sock, fd_set* active_fd_set, fd_set* read_fd_set) {int index = 0;for (index = 0; index < FD_SETSIZE; ++index) {if (FD_ISSET(index, read_fd_set)) {deal_socket(index, listen_sock, active_fd_set, read_fd_set);}}
}
? ? ? ? 再進(jìn)行測(cè)試,我們得出以下結(jié)果


? ? ? ? deal_request函數(shù)函數(shù)內(nèi)部理論上最大調(diào)用deal_socket的次數(shù)是30萬*1024=3072萬,而實(shí)際調(diào)用deal_socket的次數(shù)只有60萬。這說明平均一次調(diào)用deal_request只會(huì)有2個(gè)socket被命中從而調(diào)用deal_socket。也就是說,1次select操作只有2個(gè)socket會(huì)被處理,而其他1022次循環(huán)操作都是不被命中的比較。而恰恰最耗時(shí)的就是deal_request操作(deal_socket操作占用deal_request時(shí)間不足2%),所以我們可以得出select模型中最耗時(shí)的就是對(duì)socket的遍歷操作。而其根本原因是select函數(shù)每次返回時(shí)可以被處理的socket數(shù)量太少——2個(gè)。

? ? ? ? 那么epoll和poll模型的循環(huán)使用率是多少?我們對(duì)它們的代碼做點(diǎn)改造,我們引入兩個(gè)標(biāo)記函數(shù)——total_loop_count和deal_sock_count,前者用于統(tǒng)計(jì)一共循環(huán)了多少次,后者用于統(tǒng)計(jì)需要處理的socket多少次。我們先看Poll模型的結(jié)果。


? ? ? ? 可見Poll模型中對(duì)pollfd數(shù)組遍歷的次數(shù)一共是60萬次,有效處理socket也是60萬次。使用率100%,而不像Select模型的使用率只有60/3072=2%。同樣epoll的使用率也是100%。


? ? ? ? 通過上述分析,我們可以看出在短連接、一次性讀寫完數(shù)據(jù)的情況下,樸素模型的效率是最高的,其次是Epoll、Poll、Select。其實(shí)Select模型性能和Poll是差不多的,在我們測(cè)試場(chǎng)景下產(chǎn)生的差距是因?yàn)槲覀儗?shí)現(xiàn)Select模式的方式問題。我們對(duì)其可以參照Poll模型進(jìn)行改造,使用一個(gè)int型數(shù)組保存接入的socket,同時(shí)動(dòng)態(tài)記錄可用socket的個(gè)數(shù)。這樣我們每次遍歷就只遍歷連續(xù)的可用socket數(shù)組空間,而不用像例子中將整個(gè)數(shù)組都遍歷,從而提高循環(huán)操作的有效率。

? ? ? ? 那么什么時(shí)候才是該使用Select、Poll或者Epoll模型的呢?我們將在下一篇博文中對(duì)其進(jìn)行分析。

總結(jié)

以上是生活随笔為你收集整理的朴素、Select、Poll和Epoll网络编程模型实现和分析——模型比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。