int iResult = recv(s, buffer,1024);
/*設置非阻塞模式,立即返回*/
int iResult = ioctlsocket(s, FIOBIO, (unsigned long *)&ul);
iResult = recv(s, buffer,1024);
//5種io模型,兩個步驟,1等待數據到內核,2從內核拿數據
bio : 一直等待數據到內核,然後copy
recvfrom -> [syscall -> wait -> copy ->] return OK
nbio: 內核無數據返回,有數據然後copy
recvfrom -> [syscall -> wait ->] return no data ready
recvfrom -> [syscall -> wait ->] return no data ready
recvfrom -> [syscall -> wait ->] return ready
recvfrom -> [syscall -> copy ->] return OK
io multiplexing
每個IO都是非阻塞IO,第一階段通過select/poll方法,一次性輪詢多個IO句柄,檢查是否有IO句柄準備好,第二階段阻塞讀取數據
select/pool -> [syscall -> wait ->] return readable
recvfrom -> [syscall -> copy ->] return OK
NIO和IO多路複用是兩個相對獨立的事情,IO多路複用和NIO是要配合一起使用纔有實際
//select
支持了同一個線程內同時處理多個IO請求
每次所有fd到內核,內核每次遍歷所有fd,數量有限
可以cat/proc/sys/fs/file-max察看。32位機默認是1024個。64位機默認是2048
sizeof(fd_set)=512,每bit表示一個文件描述符,支持的最大文件描述符是512*8=4096
//poll
poll沒有最大文件描述符數量的限制
使用pollfd結構而不是select的fd_set結構
//epoll
epoll_create是創建一個epoll句柄;epoll_ctl是註冊要監聽的事件類型;epoll_wait則是等待事件的產生
epoll保證了每個fd在整個過程中只會拷貝一次
雖然都要睡眠和交替,但是select和poll在“醒着”的時候要遍歷整個fd集合,
而epoll在“醒着”的時候只要判斷一下就緒鏈表是否爲空就行了,這節省了大量的CPU時間
水平觸發和邊沿觸發,有數據觸發,有新數據觸發
signal driven IO
構造一個信號處理器回調,第二階段阻塞讀取數據
signal handle -> [syscall -> wait ->] return
[syscall ->] signal handle -> recvfrom -> [syscall -> copy ->] return OK
asynchronous IO
兩階段都是非阻塞
aio_read -> [syscall -> wait ->] return
[syscall -> copy ->] aio_read callback
linux的AIO的實現方式是內核和應用共享一片內存區域,來得知fd是否有數據
網絡IO select epoll
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.