多路转接select1
高級(jí)IO
通常情況下所有的 IO 都可以分為兩步來(lái)完成, 第一步等待, 第二步數(shù)據(jù)搬遷, 為了提高 IO 效率通常所運(yùn)用的方法就是減少等待的時(shí)間
舉個(gè)釣魚的例子
現(xiàn)在有五個(gè)人張三, 李四, 王五, 趙六, 錢七. 它們五個(gè)人來(lái)到湖邊來(lái)釣魚. 而它們五個(gè)人的釣魚方各不相同.
張三釣魚方法:
往魚鉤上掛上魚餌, 然后一動(dòng)不動(dòng)地盯著魚餌, 不管有任何人來(lái)叫張三, 張三誰(shuí)都不理, 唯一關(guān)注的就是是否有魚上鉤, 于是就一直盯著魚漂, 只要魚漂有動(dòng)靜, 就說(shuō)明有魚上鉤, 于是將上鉤的魚拉上來(lái).
李四釣魚方法:
將魚餌往魚鉤上一掛, 將魚鉤和魚餌全部扔到河里, 然后他一邊釣魚, 一邊玩手機(jī), 然后問(wèn)一下張三釣了多少魚, 但是張三一直關(guān)注的是自己的魚漂是否有動(dòng)靜, 它根本就不理李四, 玩一會(huì)兒手機(jī)定期看一下是否有魚上鉤.
王五釣魚方法:
王五比較聰明, 他看到張三和李四兩個(gè)人一個(gè)在那里傻傻地盯著魚漂, 一個(gè)像話嘮一樣一直問(wèn)著旁邊的人,于是他相處了一個(gè)辦法, 他往掛魚餌的那個(gè)地方掛一個(gè)鈴鐺, 只要鈴鐺一響, 他便將魚從水里拉出來(lái). 如果鈴鐺沒(méi)有響, 自己該干什么就干什么.
趙六釣魚方法:
趙六相比前面的張三, 李四, 王五來(lái)說(shuō)比較富裕, 他來(lái)的時(shí)候拿了好多個(gè)魚竿, 于是他將所有的魚竿往岸邊一插, 并且對(duì)這些魚竿進(jìn)行編號(hào), 然后不斷地對(duì)這些所有的魚竿進(jìn)行便利檢測(cè), 只要其中那個(gè)魚漂有動(dòng)靜, 就將魚鉤拉上來(lái).
錢七釣魚方法:
錢七是一個(gè)大土豪, 他來(lái)的時(shí)候是由自己的專門司機(jī)開著名車將自己帶過(guò)來(lái)的, 于是他將魚鉤交給自己的司機(jī), 告訴他, 你幫我釣魚, 等你釣完魚, 下午的時(shí)候給我打電話, 我直接來(lái)拿魚就可以了. 于是去忙自己的事了.
總結(jié)
通過(guò)上面的這個(gè)例子, 我們可以看出來(lái)張三, 李四, 王五, 趙六他們都有一個(gè)特性, 那就是等待魚上鉤自己等待, 將魚拉上來(lái)也是自己干, 而錢七相比前面的四個(gè)人而言也就是等待魚兒上鉤是別人替自己等, 魚拉上來(lái)也是別人幫自己拉上來(lái), 而自己唯一要做的就是將釣魚這件事發(fā)起, 然后交給某個(gè)人就可以了.
如果將上面的釣魚的例子對(duì)應(yīng)到我們的IO模型中的話, 那么前四種就是對(duì)應(yīng)的同步IO, 即等待和數(shù)據(jù)搬遷都由自己來(lái)完成, 而最后一種就是對(duì)應(yīng)的異步 IO, 數(shù)據(jù)搬遷和等待都不需要自己來(lái)完成, 自己唯一干的就是發(fā)起某個(gè)事件.同時(shí)張三對(duì)應(yīng)的IO模型就是阻塞方式, 李四就是非阻塞方式, 王五為驅(qū)動(dòng)方式, 趙六為多路轉(zhuǎn)接模型, 錢七為異步方式
幾個(gè)概念
同步IO事件由自己發(fā)起, 就緒事件的等待由自己完成, 數(shù)據(jù)的搬遷也是由自己來(lái)完成.
異步IO事件由自己發(fā)起, 就緒事件的等待, 數(shù)據(jù)的搬遷都由別人幫自己完成
輪詢不斷的檢測(cè)就緒事件是否發(fā)生, 輪詢是基于非阻塞接口.
IO多路轉(zhuǎn)接一次可以監(jiān)視多個(gè)文件描述符, 就好比趙六一次可以監(jiān)視多個(gè)魚竿
阻塞和非阻塞的不同
阻塞和非阻塞的不同之處在于等待方式的不同, 阻塞方式就是只要就緒事件沒(méi)有發(fā)生, 則一直等待, 而非阻塞方式就是不斷檢測(cè), 如果有就緒事件發(fā)生, 就處理就緒事件, 如果沒(méi)有就緒事件就返回, 然后過(guò)一段時(shí)間時(shí)間再進(jìn)行檢測(cè).
五種 IO 模型
阻塞方式在內(nèi)核將數(shù)據(jù)準(zhǔn)備好之間, 系統(tǒng)一直等待, 所有的套接字默認(rèn)為阻塞方式.
非阻塞方式需要程序員不斷循環(huán)反復(fù)嘗試讀寫文件描述符.
信號(hào)驅(qū)動(dòng)內(nèi)核將數(shù)據(jù)準(zhǔn)備好的時(shí)候, 于是便給當(dāng)前應(yīng)用程序發(fā)送一個(gè)SIGIO信號(hào),當(dāng)前應(yīng)用進(jìn)程收到這個(gè)信號(hào)的額時(shí)候, 于是便知道底層的就緒事件已經(jīng)發(fā)生, 于是就進(jìn)行 IO 操作
**IO多路轉(zhuǎn)接**IO多路轉(zhuǎn)接一次可以等待多個(gè)文件描述符的就緒事件
異步IO由內(nèi)核在數(shù)據(jù)拷貝完成的時(shí)候通知應(yīng)用進(jìn)程(信號(hào)驅(qū)動(dòng)對(duì)應(yīng)的就是高速應(yīng)用進(jìn)程何時(shí)可以進(jìn)行數(shù)據(jù)搬遷)
高級(jí)IO重要概念
同步IO VS 異步IO
同步IO在發(fā)出一個(gè)調(diào)用的時(shí)候, 在沒(méi)有得到結(jié)果之前, 該調(diào)用不會(huì)返回, 但是一旦調(diào)用返回, 就得到返回值, 即由調(diào)用者主動(dòng)等待調(diào)用結(jié)果.
異步IO調(diào)用在發(fā)出之后, 這個(gè)調(diào)用就會(huì)返回, 沒(méi)有返回結(jié)果. 換言之就是當(dāng)一個(gè)異步調(diào)用發(fā)出之后, 調(diào)用者不會(huì)立即等到結(jié)果, 而是在調(diào)用之后, 由被調(diào)用者通過(guò)狀態(tài)通知調(diào)用者, 或者通過(guò)回調(diào)函數(shù)來(lái)處理這個(gè)函數(shù).
非阻塞相關(guān)接口
fcntl
我們都知道文件描述符默認(rèn)都是阻塞 IO
#include<unistd.h> #include<fcntl.h>int fcntl(int fd, int cmd, .../*arg*/);其中 fd 為文件描述符, 表示要對(duì)哪一個(gè)文件描述符進(jìn)行設(shè)置, cmd取值不同時(shí)代表了不同的方式
cmd = F_DUPFD 時(shí)代表復(fù)制一個(gè)文件描述符
cmd = FGETFD 或者 FSETFD 時(shí)代表獲得文件描述符標(biāo)記
實(shí)現(xiàn)一個(gè)非阻塞文件描述符
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h>void SetNoBlock(int fd) {int f1 = fcntl(fd, F_GETFL);if(fd < 0){perror("fd");exit(1);}fcntl(fd, F_SETFL, f1 | O_NONBLOCK); } int main() {SetNoBlock(0);while(1){char buf[1024] = {0};ssize_t s = read(0, buf, sizeof(buf));if(s < 0){perror("read");//底層未將數(shù)據(jù)準(zhǔn)備好sleep(1);continue;}printf("input %s\n", buf);}return 0; }重定向
曾近我們學(xué)習(xí)過(guò)將數(shù)據(jù)重定向即就是將某個(gè)文件符關(guān)閉, 然后打開文件描述符,此時(shí)對(duì)關(guān)閉的那個(gè)文件描述符進(jìn)行操作便會(huì)成為對(duì)文件的操作.
dup/dup2
#include <unistd.h>int dup(int oldfd);int dup2(int oldfd, int newfd);總結(jié)
以上是生活随笔為你收集整理的多路转接select1的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 输卵管黏连手术多少钱
- 下一篇: 3_V1-类和对象 -- 默认成员函数