共計(jì) 2837 個(gè)字符,預(yù)計(jì)需要花費(fèi) 8 分鐘才能閱讀完成。
這篇文章主要講解了“l(fā)inux 中 poll 和 select 有哪些區(qū)別”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“l(fā)inux 中 poll 和 select 有哪些區(qū)別”吧!
linux 中 poll 和 select 的區(qū)別是:select 單個(gè)進(jìn)程所能打開的最大連接數(shù)由“FD_SETSIZE”宏定義,其大小是 32 個(gè)整數(shù)的大小,而 poll 因?yàn)椴捎面湵泶鎯?chǔ),所以沒有最大連接數(shù)的限制。
本教程操作環(huán)境:linux7.3 系統(tǒng)、Dell G3 電腦。
linux 中 poll 和 select 的區(qū)別
每個(gè)進(jìn)程使用的 select 有最大連接數(shù)限制,只能有 FD_SETSIZE 個(gè),而 poll 沒有這樣的限制(采用鏈表存儲(chǔ));
epoll 跟 select 都能提供多路 I / O 復(fù)用的解決方案。在現(xiàn)在的 Linux 內(nèi)核里有都能夠支持,其中 epoll 是 Linux 所特有,而 select 則應(yīng)該是 POSIX 所規(guī)定,一般操作系統(tǒng)均有實(shí)現(xiàn)
select:
select 本質(zhì)上是通過設(shè)置或者檢查存放 fd 標(biāo)志位的數(shù)據(jù)結(jié)構(gòu)來進(jìn)行下一步處理。這樣所帶來的缺點(diǎn)是:
1、單個(gè)進(jìn)程可監(jiān)視的 fd 數(shù)量被限制,即能監(jiān)聽端口的大小有限。
一般來說這個(gè)數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大,具體數(shù)目可以 cat /proc/sys/fs/file-max 察看。32 位機(jī)默認(rèn)是 1024 個(gè)。64 位機(jī)默認(rèn)是 2048.
2、對(duì) socket 進(jìn)行掃描時(shí)是線性掃描,即采用輪詢的方法,效率較低:
當(dāng)套接字比較多的時(shí)候,每次 select()都要通過遍歷 FD_SETSIZE 個(gè) Socket 來完成調(diào)度, 不管哪個(gè) Socket 是活躍的, 都遍歷一遍。這會(huì)浪費(fèi)很多 CPU 時(shí)間。如果能給套接字注冊(cè)某個(gè)回調(diào)函數(shù),當(dāng)他們活躍時(shí),自動(dòng)完成相關(guān)操作,那就避免了輪詢,這正是 epoll 與 kqueue 做的。
3、需要維護(hù)一個(gè)用來存放大量 fd 的數(shù)據(jù)結(jié)構(gòu),這樣會(huì)使得用戶空間和內(nèi)核空間在傳遞該結(jié)構(gòu)時(shí)復(fù)制開銷大
poll:
poll 本質(zhì)上和 select 沒有區(qū)別,它將用戶傳入的數(shù)組拷貝到內(nèi)核空間,然后查詢每個(gè) fd 對(duì)應(yīng)的設(shè)備狀態(tài),如果設(shè)備就緒則在設(shè)備等待隊(duì)列中加入一項(xiàng)并繼續(xù)遍歷,如果遍歷完所有 fd 后沒有發(fā)現(xiàn)就緒設(shè)備,則掛起當(dāng)前進(jìn)程,直到設(shè)備就緒或者主動(dòng)超時(shí),被喚醒后它又要再次遍歷 fd。這個(gè)過程經(jīng)歷了多次無謂的遍歷。
它沒有最大連接數(shù)的限制,原因是它是基于鏈表來存儲(chǔ)的,但是同樣有一個(gè)缺點(diǎn):
1、大量的 fd 的數(shù)組被整體復(fù)制于用戶態(tài)和內(nèi)核地址空間之間,而不管這樣的復(fù)制是不是有意義。
2、poll 還有一個(gè)特點(diǎn)是“水平觸發(fā)”,如果報(bào)告了 fd 后,沒有被處理,那么下次 poll 時(shí)會(huì)再次報(bào)告該 fd。
epoll:
epoll 有 EPOLLLT 和 EPOLLET 兩種觸發(fā)模式,LT 是默認(rèn)的模式,ET 是“高速”模式。LT 模式下,只要這個(gè) fd 還有數(shù)據(jù)可讀,每次 epoll_wait 都會(huì)返回它的事件,提醒用戶程序去操作,而在 ET(邊緣觸發(fā))模式中,它只會(huì)提示一次,直到下次再有數(shù)據(jù)流入之前都不會(huì)再提示了,無 論 fd 中是否還有數(shù)據(jù)可讀。所以在 ET 模式下,read 一個(gè) fd 的時(shí)候一定要把它的 buffer 讀光,也就是說一直讀到 read 的返回值小于請(qǐng)求值,或者 遇到 EAGAIN 錯(cuò)誤。還有一個(gè)特點(diǎn)是,epoll 使用“事件”的就緒通知方式,通過 epoll_ctl 注冊(cè) fd,一旦該 fd 就緒,內(nèi)核就會(huì)采用類似 callback 的回調(diào)機(jī)制來激活該 fd,epoll_wait 便可以收到通知。
epoll 為什么要有 EPOLLET 觸發(fā)模式?
如果采用 EPOLLLT 模式的話,系統(tǒng)中一旦有大量你不需要讀寫的就緒文件描述符,它們每次調(diào)用 epoll_wait 都會(huì)返回,這樣會(huì)大大降低處理程序檢索自己關(guān)心的就緒文件描述符的效率.。而采用 EPOLLET 這種邊沿觸發(fā)模式的話,當(dāng)被監(jiān)控的文件描述符上有可讀寫事件發(fā)生時(shí),epoll_wait()會(huì)通知處理程序去讀寫。如果這次沒有把數(shù)據(jù)全部讀寫完 (如讀寫緩沖區(qū)太小),那么下次調(diào)用 epoll_wait() 時(shí),它不會(huì)通知你,也就是它只會(huì)通知你一次,直到該文件描述符上出現(xiàn)第二次可讀寫事件才會(huì)通知你!??!這種模式比水平觸發(fā)效率高,系統(tǒng)不會(huì)充斥大量你不關(guān)心的就緒文件描述符
epoll 的優(yōu)點(diǎn):
1、沒有最大并發(fā)連接的限制,能打開的 FD 的上限遠(yuǎn)大于 1024(1G 的內(nèi)存上能監(jiān)聽約 10 萬個(gè)端口);
2、效率提升,不是輪詢的方式,不會(huì)隨著 FD 數(shù)目的增加效率下降。只有活躍可用的 FD 才會(huì)調(diào)用 callback 函數(shù);
即 Epoll 最大的優(yōu)點(diǎn)就在于它只管你“活躍”的連接,而跟連接總數(shù)無關(guān),因此在實(shí)際的網(wǎng)絡(luò)環(huán)境中,Epoll 的效率就會(huì)遠(yuǎn)遠(yuǎn)高于 select 和 poll。
3、內(nèi)存拷貝,利用 mmap()文件映射內(nèi)存加速與內(nèi)核空間的消息傳遞;即 epoll 使用 mmap 減少?gòu)?fù)制開銷。
select、poll、epoll 區(qū)別總結(jié):
1、支持一個(gè)進(jìn)程所能打開的最大連接數(shù)
select
單個(gè)進(jìn)程所能打開的最大連接數(shù)有 FD_SETSIZE 宏定義,其大小是 32 個(gè)整數(shù)的大?。ㄔ?32 位的機(jī)器上,大小就是 3232,同理 64 位機(jī)器上 FD_SETSIZE 為 3264),當(dāng)然我們可以對(duì)進(jìn)行修改,然后重新編譯內(nèi)核,但是性能可能會(huì)受到影響,這需要進(jìn)一步的測(cè)試。
poll
poll 本質(zhì)上和 select 沒有區(qū)別,但是它沒有最大連接數(shù)的限制,原因是它是基于鏈表來存儲(chǔ)的
epoll
雖然連接數(shù)有上限,但是很大,1G 內(nèi)存的機(jī)器上可以打開 10 萬左右的連接,2G 內(nèi)存的機(jī)器可以打開 20 萬左右的連接
2、FD 劇增后帶來的 IO 效率問題
select
因?yàn)槊看握{(diào)用時(shí)都會(huì)對(duì)連接進(jìn)行線性遍歷,所以隨著 FD 的增加會(huì)造成遍歷速度慢的“線性下降性能問題”。
poll
同上
epoll
因?yàn)?epoll 內(nèi)核中實(shí)現(xiàn)是根據(jù)每個(gè) fd 上的 callback 函數(shù)來實(shí)現(xiàn)的,只有活躍的 socket 才會(huì)主動(dòng)調(diào)用 callback,所以在活躍 socket 較少的情況下,使用 epoll 沒有前面兩者的線性下降的性能問題,但是所有 socket 都很活躍的情況下,可能會(huì)有性能問題。
3、消息傳遞方式
select
內(nèi)核需要將消息傳遞到用戶空間,都需要內(nèi)核拷貝動(dòng)作
poll
同上
epoll
epoll 通過內(nèi)核和用戶空間共享一塊內(nèi)存來實(shí)現(xiàn)的。
總結(jié):
綜上,在選擇 select,poll,epoll 時(shí)要根據(jù)具體的使用場(chǎng)合以及這三種方式的自身特點(diǎn)。
1、表面上看 epoll 的性能最好,但是在連接數(shù)少并且連接都十分活躍的情況下,select 和 poll 的性能可能比 epoll 好,畢竟 epoll 的通知機(jī)制需要很多函數(shù)回調(diào)。
2、select 低效是因?yàn)槊看嗡夹枰喸?。但低效也是相?duì)的,視情況而定,也可通過良好的設(shè)計(jì)改善
感謝各位的閱讀,以上就是“l(fā)inux 中 poll 和 select 有哪些區(qū)別”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì) linux 中 poll 和 select 有哪些區(qū)別這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!