PHP7中I/O模型內(nèi)核剖析詳解
1.同步:我客戶端(C端調(diào)用者)一個(gè)功能,該功能沒(méi)有結(jié)束前,我死等結(jié)果。
2.異步:我(c端調(diào)用者)調(diào)用一個(gè)功能,不知道該功能結(jié)果,該功能有結(jié)果后通知我,即回調(diào)通知
3.阻塞:就是調(diào)用我(s端被調(diào)用者,函數(shù)),我(s端被調(diào)用者,函數(shù))沒(méi)有完全接受完數(shù)據(jù)或者沒(méi)有得到結(jié)果之前,我不會(huì)返回。
4.非阻塞:就是調(diào)用我(s端被調(diào)用者,函數(shù)),我(s端被調(diào)用者,函數(shù))立即返回,得出結(jié)果后通知調(diào)用者
五種I/O模型
(1) 阻塞I/O (Blocking I/O)
當(dāng)用戶進(jìn)程進(jìn)行系統(tǒng)調(diào)用時(shí),內(nèi)核就開(kāi)始了I/O的第一個(gè)階段,準(zhǔn)備數(shù)據(jù)到緩沖區(qū)中,當(dāng)數(shù)據(jù)都準(zhǔn)備完成后,則將數(shù)據(jù)從內(nèi)核緩沖區(qū)中拷貝到用戶進(jìn)程的內(nèi)存中,這時(shí)用戶進(jìn)程才解除block的狀態(tài)重新運(yùn)行。
(2) 非阻塞I/O (Non-Blocking I/O)
用戶進(jìn)程只有在第二個(gè)階段被阻塞了,而第一個(gè)階段沒(méi)有阻塞,但是在第一個(gè)階段中,用戶進(jìn)程不需要盲等,不停的去輪詢內(nèi)核,看數(shù)據(jù)是否準(zhǔn)備好了,因此該模型是比較消耗CPU的。
(3) I/O復(fù)用(I/O Multiplexing)
I/O執(zhí)行的兩個(gè)階段都是用戶進(jìn)程都是阻塞的,但是兩個(gè)階段是獨(dú)立的,在一次完整的I/O操作中,該用戶進(jìn)程是發(fā)起了兩次系統(tǒng)調(diào)用。和阻塞I/O不同的是第一段可以等待多個(gè)描述符就緒
(4) 信號(hào)驅(qū)動(dòng)的I/O (Signal Driven I/O)
只有在I/O執(zhí)行的第二階段阻塞了用戶進(jìn)程,而在第一階段是沒(méi)有阻塞的。該模型在I/O執(zhí)行的第一階段,當(dāng)數(shù)據(jù)準(zhǔn)備完成之后,會(huì)主動(dòng)的通知用戶進(jìn)程數(shù)據(jù)已經(jīng)準(zhǔn)備完成,即對(duì)用戶進(jìn)程做一個(gè)回調(diào)。該通知分為兩種,一為水平觸發(fā),即如果用戶進(jìn)程不響應(yīng)則會(huì)一直發(fā)送通知,二為邊緣觸發(fā),即只通知一次。
(5) 異步I/O (Asynchrnous I/O)
當(dāng)用戶進(jìn)程發(fā)起系統(tǒng)調(diào)用后,立刻就可以開(kāi)始去做其它的事情,然后直到I/O執(zhí)行的兩個(gè)階段都完成之后,內(nèi)核會(huì)給用戶進(jìn)程發(fā)送通知,告訴用戶進(jìn)程操作已經(jīng)完成了。
I/O多路復(fù)用技術(shù)
select
(1).select()的機(jī)制中提供一fd_set的數(shù)據(jù)結(jié)構(gòu),每一個(gè)元素都能與一打開(kāi)的文件句柄(不管是Socket句柄,還是其他 文件或命名管道或設(shè)備句柄)建立聯(lián)系,建立聯(lián)系的工作由程序員完成, 當(dāng)調(diào)用select()時(shí),由內(nèi)核根據(jù)IO狀態(tài)修改fd_set的內(nèi)容,由此來(lái)通知執(zhí)行了select()的進(jìn)程哪一Socket或文件可讀或可寫(xiě)。主要用于Socket通信當(dāng)中。
(2).程序執(zhí)行select后,如果沒(méi)有數(shù)據(jù)輸入,程序會(huì)一直等待(阻塞時(shí)),直到有數(shù)據(jù)為止,也就是程序中無(wú)需循環(huán)和sleep。
(3).每次調(diào)用select,都需要把fd_set集合從用戶態(tài)拷貝到內(nèi)核態(tài),這個(gè)開(kāi)銷在fd_set很多時(shí)會(huì)很大
(4).同時(shí)每次調(diào)用select都需要在內(nèi)核遍歷傳遞進(jìn)來(lái)的所有fd_set,這個(gè)開(kāi)銷在fd_set很多時(shí)也很大
(5).select支持的文件描述符數(shù)量太小了,默認(rèn)是1024
poll
(1).poll的實(shí)現(xiàn)和select非常相似,只是描述fd_set集合的方式不同,poll使用pollfd鏈表結(jié)構(gòu)而不是select的fd_set結(jié)構(gòu),其他的都差不多。
(2).監(jiān)視描述符個(gè)數(shù)無(wú)上限;
epoll/kqueue
(1).監(jiān)視描述符個(gè)數(shù)無(wú)上限;
(2).效率提升,不是輪詢的方式,不會(huì)隨著fd數(shù)目的增加效率下降。只有活躍可用的fd才會(huì)調(diào)用callback函數(shù);即epoll/kqueue最大的優(yōu)點(diǎn)就在于它只管你“活躍”的連接,而跟連接總數(shù)無(wú)關(guān),因此在實(shí)際的網(wǎng)絡(luò)環(huán)境中,epoll/kqueue的效率就會(huì)遠(yuǎn)遠(yuǎn)高于select和poll。
(3).內(nèi)存拷貝,利用mmap()文件映射內(nèi)存加速與內(nèi)核空間的消息傳遞;
相關(guān)文章
PHP實(shí)現(xiàn)數(shù)據(jù)庫(kù)統(tǒng)計(jì)時(shí)間戳按天分組輸出數(shù)據(jù)的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)數(shù)據(jù)庫(kù)統(tǒng)計(jì)時(shí)間戳按天分組輸出數(shù)據(jù)的方法,涉及php基于時(shí)間的運(yùn)算與數(shù)據(jù)庫(kù)查詢相關(guān)操作技巧,需要的朋友可以參考下2017-10-10Swoole 1.10.0新版本發(fā)布,增加了多項(xiàng)新特性
最近Swoole 1.10.0版本發(fā)布了,增加多項(xiàng)新特性,所以下面這篇文章主要給大家介紹了關(guān)于Swoole 1.10.0版本中新特性的相關(guān)資料,分享出來(lái)供大家參考學(xué)習(xí),需要的朋友可以參考下2018-01-01Content-Disposition使用方法和注意事項(xiàng)
這篇文章主要為大家詳細(xì)介紹了Content-Disposition使用方法和注意事項(xiàng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09PHP內(nèi)置過(guò)濾器FILTER使用實(shí)例
這篇文章主要介紹了PHP內(nèi)置過(guò)濾器FILTER使用實(shí)例,列舉了驗(yàn)證功能和糾錯(cuò)功能的代碼例子來(lái)講解如何使用FILTER,需要的朋友可以參考下2014-06-06php 函數(shù)使用可變數(shù)量的參數(shù)方法
下面小編就為大家?guī)?lái)一篇php 函數(shù)使用可變數(shù)量的參數(shù)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-05-05PHP 進(jìn)度條函數(shù)的簡(jiǎn)單實(shí)例
這篇文章主要介紹了PHP 進(jìn)度條函數(shù)的簡(jiǎn)單實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09PHP實(shí)現(xiàn)格式化文件數(shù)據(jù)大小顯示的方法
這篇文章主要介紹了PHP實(shí)現(xiàn)格式化文件數(shù)據(jù)大小顯示的方法,通過(guò)一個(gè)自定義函數(shù)實(shí)現(xiàn)針對(duì)文件大小的精確格式化,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01