https://blog.csdn.net/ZWE7616175/article/details/80591587
在網(wǎng)絡環(huán)境下,通俗的講灌旧,將IO分為兩步:
1.等绑咱;
2.數(shù)據(jù)搬遷。
如果要想提高IO效率枢泰,需要將等的時間降低描融。
五種IO模型包括:阻塞IO、非阻塞IO衡蚂、信號驅動IO窿克、IO多路轉接、異步IO讳窟。其中让歼,前四個被稱為同步IO。
在介紹五種IO模型時丽啡,我會舉生活中釣魚的例子谋右,加深理解。
1.阻塞IO(blocking I/O)
A拿著一支魚竿在河邊釣魚补箍,并且一直在魚竿前等改执,在等的時候不做其他的事情,十分專心坑雅。只有魚上鉤的時辈挂,才結束掉等的動作,把魚釣上來裹粤。
在內(nèi)核將數(shù)據(jù)準備好之前终蒂,系統(tǒng)調(diào)用會一直等待所有的套接字,默認的是阻塞方式遥诉。
其實拇泣,我們例子中所說的魚竿就是這一個文件描述符。這個模型是我們最常見的矮锈,程序調(diào)用和我們編寫的基本程序是一致的霉翔。
fd=connect();
write(fd);
read(fd);
close(fd);
程序的read必須在write之后執(zhí)行,當write阻塞住了苞笨,read就不能執(zhí)行下去债朵,一直處于等待狀態(tài)。
2.非阻塞IO(noblocking I/O)
B也在河邊釣魚瀑凝,但是B不想將自己的所有時間都花費在釣魚上序芦,在等魚上鉤這個時間段中,B也在做其他的事情(一會看看書粤咪,一會讀讀報紙芝加,一會又去看其他人的釣魚等),但B在做這些事情的時候,每隔一個固定的時間檢查魚是否上鉤藏杖。一旦檢查到有魚上鉤,就停下手中的事情脉顿,把魚釣上來蝌麸。
其實,B在檢查魚竿是否有魚艾疟,是一個輪詢的過程来吩。
每次客戶詢問內(nèi)核是否有數(shù)據(jù)準備好,即文件描述符緩沖區(qū)是否就緒蔽莱。當有數(shù)據(jù)報準備好時弟疆,就進行拷貝數(shù)據(jù)報的操作。當沒有數(shù)據(jù)報準備好時盗冷,也不阻塞程序怠苔,內(nèi)核直接返回未準備就緒的信號,等待用戶程序的下一個輪尋仪糖。
但是柑司,輪尋對于CPU來說是較大的浪費,一般只有在特定的場景下才使用锅劝。
3.信號驅動IO(signal blocking I/O)
C也在河邊釣魚攒驰,但與A、B不同的是故爵,C比較聰明玻粪,他給魚竿上掛一個鈴鐺,當有魚上鉤的時候诬垂,這個鈴鐺就會被碰響劲室,C就會將魚釣上來。
信號驅動IO模型剥纷,應用進程告訴內(nèi)核:當數(shù)據(jù)報準備好的時候痹籍,給我發(fā)送一個信號,對SIGIO信號進行捕捉晦鞋,并且調(diào)用我的信號處理函數(shù)來獲取數(shù)據(jù)報蹲缠。
4.IO多路轉接(I/O multiplexing)
D同樣也在河邊釣魚,但是D生活水平比較好悠垛,D拿了很多的魚竿线定,一次性有很多魚竿在等,D不斷的查看每個魚竿是否有魚上鉤确买。增加了效率斤讥,減少了等待的時間。
IO多路轉接是多了一個select函數(shù),select函數(shù)有一個參數(shù)是文件描述符集合芭商,對這些文件描述符進行循環(huán)監(jiān)聽派草,當某個文件描述符就緒時,就對這個文件描述符進行處理铛楣。
其中近迁,select只負責等,recvfrom只負責拷貝簸州。
IO多路轉接是屬于阻塞IO鉴竭,但可以對多個文件描述符進行阻塞監(jiān)聽,所以效率較阻塞IO的高岸浑。
5.異步IO(asynchronous I/O)
E也想釣魚搏存,但E有事情,于是他雇來了F矢洲,讓F幫他等待魚上鉤璧眠,一旦有魚上鉤,F(xiàn)就打電話給E兵钮,E就會將魚釣上去蛆橡。
當應用程序調(diào)用aio_read時,內(nèi)核一方面去取數(shù)據(jù)報內(nèi)容返回掘譬,另一方面將程序控制權還給應用進程泰演,應用進程繼續(xù)處理其他事情,是一種非阻塞的狀態(tài)葱轩。
當內(nèi)核中有數(shù)據(jù)報就緒時睦焕,由內(nèi)核將數(shù)據(jù)報拷貝到應用程序中,返回aio_read中定義好的函數(shù)處理程序靴拱。
很少有Linux系統(tǒng)支持垃喊,Windows的IOCP就是該模型。
可以看出袜炕,阻塞程度:阻塞IO>非阻塞IO>多路轉接IO>信號驅動IO>異步IO本谜,效率是由低到高的。