偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一篇學(xué)會阿里面試問的 Select、Poll、Epoll 模型

開發(fā) 前端
epoll沒有這個限制,它所支持的FD上限是最大可以打開文件的數(shù)目,這個數(shù)字一般遠(yuǎn)大于1024,舉個例子,在1GB內(nèi)存的機(jī)器上大約是10萬左右,具體數(shù)目可以cat /proc/sys/fs/file-max察看,一般來說這個數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大。

這一篇要說的select、poll、epoll這三個的區(qū)別,大家對于IO多路復(fù)用都了解吧,這個問題也是面試官最最愛問的問題之一了。

操作系統(tǒng)在處理IO的時(shí)候,主要客源分為兩個階段:

  • 等待數(shù)據(jù)傳遞到IO設(shè)備。
  • IO設(shè)備將數(shù)據(jù)復(fù)制到用戶空間user space。

也就可以將上述過程簡化理解為:

等待數(shù)據(jù)到kernel內(nèi)核區(qū)域。

kernel內(nèi)核區(qū)域?qū)?shù)據(jù)復(fù)制到用戶區(qū)域user space,用戶區(qū)域可以理解為JVM區(qū)域,即進(jìn)程或者線程的緩沖區(qū)。

BIO

這是屬于最簡單的同步阻塞IO模型

當(dāng)應(yīng)用層有數(shù)據(jù)過來的時(shí)候,會調(diào)用recvfrom方法,但是這個時(shí)候應(yīng)用層的數(shù)據(jù)還沒有復(fù)制到kernel內(nèi)核區(qū),也就是上面說的第一個過程,這個過程需要時(shí)間,所以recvfrom會阻塞。

當(dāng)內(nèi)核kernel中的數(shù)據(jù)準(zhǔn)備好了之后,recvfrom方法并不會返回,而是會發(fā)起一個系統(tǒng)調(diào)用將kernel中的數(shù)據(jù)復(fù)制到JVM的進(jìn)程中的緩沖區(qū)中,也就是用戶空間user space。

當(dāng)這個復(fù)制也完成之后,也就是上面說的兩個階段全部完成之后,recvfrom才會返回并且解除程序的阻塞。

圖片

默認(rèn)情況下,所有的文件操作都是阻塞的,在進(jìn)程調(diào)用期間的recvfrom,直到數(shù)據(jù)包達(dá)到并且被復(fù)制到JVM進(jìn)程緩沖區(qū)或者發(fā)生錯誤的時(shí)候才會返回,在此期間一直阻塞。

在阻塞期間,CPU不能執(zhí)行IO操作,但是CPU還是可以去做別的事情的,阻塞了,但沒有完全阻塞。

我們再看操作系統(tǒng)處理IO的兩個步驟

  • 等待數(shù)據(jù)到kernel內(nèi)核區(qū)域
  • kernel內(nèi)核區(qū)域?qū)?shù)據(jù)復(fù)制到用戶區(qū)域user space

阻塞IO模型,其實(shí)就是把這兩個階段合并在一起,一起阻塞。

NIO

非阻塞其實(shí)就是把第一個過程的阻塞變成非阻塞,也就是recvfrom函數(shù)會不斷的去詢問kernel內(nèi)核區(qū)域中的數(shù)據(jù)是否準(zhǔn)備好。

如果數(shù)據(jù)沒有準(zhǔn)備好,就返回EWOULDBLOCK錯誤,不斷的去進(jìn)行輪詢檢查,知道發(fā)現(xiàn)kernel內(nèi)核中的數(shù)據(jù)準(zhǔn)備好了,就會返回。

第二個階段屬于系統(tǒng)調(diào)用,是必須阻塞的,就是將數(shù)據(jù)從kernel內(nèi)核區(qū)域拷貝到用戶區(qū)域,也就是進(jìn)程緩沖區(qū)中。

圖片

Linux系統(tǒng)將所有設(shè)備都當(dāng)作文件來處理,而Linux用文件描述符fd來標(biāo)識每個文件對象。

問題

阻塞模型在沒有收到數(shù)據(jù)的時(shí)候就會阻塞卡主,如果一個線程需要接受到多個客戶端的socket的fd連接,這樣會導(dǎo)致在處理這種情況效率比較低。

必須處理完前面的所有fd,才可以處理后面的fd,即使后面的fd可能比前面的fd提前準(zhǔn)備好了,但是也得等,這樣會導(dǎo)致客戶端的嚴(yán)重延遲。

于是為了處理多個請求,有的小伙伴可能會想到用多個線程來改善,可以引入線程池改善這個情況,并且通過線程池的最大數(shù)量來控制這個限度,但是這并沒有從根本上解決問題。

應(yīng)用:適用于針對大量的io請求的情況,對于服務(wù)器必須在同時(shí)處理來自客戶端的大量的io操作的時(shí)候,就非常適合。

圖片

Select工作流程

單個進(jìn)程可以同時(shí)處理多個網(wǎng)絡(luò)連接的IO請求,就是調(diào)用select之后,整個程序就阻塞了。

此時(shí)需要把所有的fd集合都從JVM用戶空間拷貝到kernel內(nèi)核空間,這個開銷很大。

然后去輪詢檢查所有的select負(fù)責(zé)的fd,當(dāng)找到一個client中的數(shù)據(jù)準(zhǔn)備好了之后,select就會返回,此時(shí)將數(shù)據(jù)從kernel復(fù)制到進(jìn)程的緩沖區(qū)中。

圖片

缺點(diǎn):

  • 每次都需要把fd集合從用戶態(tài)拷貝到內(nèi)核態(tài),消耗資源。
  • 每次調(diào)用需要進(jìn)行輪詢所有傳遞進(jìn)來的fd,也比較消耗資源。

你想啊,要是有十萬個連接,而活躍的只有幾個,那每次都要遍歷這十萬個,豈不是很糟糕。

  • 支持的fd數(shù)量有限,根據(jù)fd_size的定義,它的大小為32個整數(shù)大小(32位機(jī)器為32*32,所有共有1024bits可以記錄fd),每個fd一個bit,所以最大只能同時(shí)處理1024個fd。

每一次呼叫select都需要先從 user space把 FD_SET復(fù)制到 kernel(約線性時(shí)間成本)。

為什么 select 不能像epoll一樣,只做一次復(fù)制就好呢?

每一次呼叫 select()前,F(xiàn)D_SET都可能更動,而 epoll 提供了共享記憶存儲結(jié)構(gòu),所以不需要這里的kernel內(nèi)核區(qū)域和用戶區(qū)域之間的全量數(shù)據(jù)復(fù)制。

Poll

poll的原理與select非常相似,但是呢,有兩點(diǎn)的不同之處。

一個是存儲fd的集合不同,select是有限的,而poll的方式存儲是鏈?zhǔn)降?,沒有最大連接數(shù)的限制。

另一點(diǎn)就是水平觸發(fā),也就是通知程序fd就緒后,這次沒有被處理,那么下次poll的時(shí)候會再次通知同個fd已經(jīng)就緒。

Epoll

epoll既然是對select和poll的改進(jìn),就應(yīng)該能避免上述的三個缺點(diǎn)。那epoll都是怎么解決的呢?

在此之前,我們先看一下epoll和select和poll的調(diào)用接口上的不同,select和poll都只提供了一個函數(shù)——select或者poll函數(shù)。而epoll提供了三個函數(shù),epoll_create,epoll_ctl和epoll_wait。

epoll_create是創(chuàng)建一個epoll句柄;epoll_ctl是注冊要監(jiān)聽的事件類型;epoll_wait則是等待事件的產(chǎn)生。

對于每次都需要把數(shù)據(jù)從用戶區(qū)全量復(fù)制到kernel內(nèi)核區(qū)這個缺點(diǎn),epoll的解決方案在epoll_ctl函數(shù)中。

每次注冊新的事件到epoll句柄中時(shí)(在epoll_ctl中指定EPOLL_CTL_ADD),會把所有的fd拷貝進(jìn)內(nèi)核,而不是在epoll_wait的時(shí)候重復(fù)拷貝。epoll保證了每個fd在整個過程中只會拷貝一次。

對于第二個每次都需要輪詢所有fd這個缺點(diǎn)

epoll的解決方案不像select或poll一樣每次都把current輪流加入fd對應(yīng)的設(shè)備等待隊(duì)列中,而只在epoll_ctl時(shí)把current掛一遍(這一遍必不可少)并為每個fd指定一個回調(diào)函數(shù),當(dāng)設(shè)備就緒,喚醒等待隊(duì)列上的等待者時(shí),就會調(diào)用這個回調(diào)函數(shù),而這個回調(diào)函數(shù)會把就緒的fd加入一個就緒鏈表)。

epoll_wait的工作實(shí)際上就是在這個就緒鏈表中查看有沒有就緒的fd(利用schedule_timeout()實(shí)現(xiàn)睡一會,判斷一會的效果,和select實(shí)現(xiàn)中的第7步是類似的)。

把主動權(quán)交給了每一個連接,當(dāng)設(shè)備就緒的時(shí)候,調(diào)用回調(diào)函數(shù)才會加入到這個就緒的集合。

對于第三個數(shù)量的缺點(diǎn)

epoll沒有這個限制,它所支持的FD上限是最大可以打開文件的數(shù)目,這個數(shù)字一般遠(yuǎn)大于1024,舉個例子,在1GB內(nèi)存的機(jī)器上大約是10萬左右,具體數(shù)目可以cat /proc/sys/fs/file-max察看,一般來說這個數(shù)目和系統(tǒng)內(nèi)存關(guān)系很大。

圖片

責(zé)任編輯:武曉燕 來源: 左耳君
相關(guān)推薦

2025-01-07 00:07:17

2020-11-04 07:49:04

Select

2021-05-31 06:50:47

SelectPoll系統(tǒng)

2022-02-22 08:55:29

SelectPoll/ Epoll

2022-01-02 08:43:46

Python

2022-02-07 11:01:23

ZooKeeper

2023-11-06 07:27:38

模型NLP領(lǐng)域

2022-06-30 22:53:18

數(shù)據(jù)結(jié)構(gòu)算法

2021-08-01 07:19:16

語言OpenrestyNginx

2021-12-04 22:05:02

Linux

2021-10-26 10:40:26

代理模式虛擬

2022-05-17 08:02:55

GoTryLock模式

2021-07-02 09:45:29

MySQL InnoDB數(shù)據(jù)

2021-07-06 08:59:18

抽象工廠模式

2023-01-03 08:31:54

Spring讀取器配置

2021-07-05 22:11:38

MySQL體系架構(gòu)

2023-11-28 08:29:31

Rust內(nèi)存布局

2021-05-11 08:54:59

建造者模式設(shè)計(jì)

2022-08-23 08:00:59

磁盤性能網(wǎng)絡(luò)

2022-08-26 09:29:01

Kubernetes策略Master
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號