日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

無(wú)法連接到internet怎么解決 無(wú)法連接到internet( 三 )


      if(–nready == 0) break;
    }
  }
}
正如剛剛的動(dòng)圖中所描述的,其直觀效果如下 。(同一個(gè)動(dòng)圖消耗了你兩次流量,氣不氣?)
可以看出幾個(gè)細(xì)節(jié):
1. select 調(diào)用需要傳入 fd 數(shù)組,需要拷貝一份到內(nèi)核,高并發(fā)場(chǎng)景下這樣的拷貝消耗的資源是驚人的 。(可優(yōu)化為不復(fù)制)
2. select 在內(nèi)核層仍然是通過(guò)遍歷的方式檢查文件描述符的就緒狀態(tài),是個(gè)同步過(guò)程,只不過(guò)無(wú)系統(tǒng)調(diào)用切換上下文的開(kāi)銷(xiāo) 。(內(nèi)核層可優(yōu)化為異步事件通知)
3. select 僅僅返回可讀文件描述符的個(gè)數(shù),具體哪個(gè)可讀還是要用戶(hù)自己遍歷 。(可優(yōu)化為只返回給用戶(hù)就緒的文件描述符,無(wú)需用戶(hù)做無(wú)效的遍歷)
整個(gè) select 的流程圖如下 。
可以看到,這種方式,既做到了一個(gè)線(xiàn)程處理多個(gè)客戶(hù)端連接(文件描述符),又減少了系統(tǒng)調(diào)用的開(kāi)銷(xiāo)(多個(gè)文件描述符只有一次 select 的系統(tǒng)調(diào)用 + n 次就緒狀態(tài)的文件描述符的 read 系統(tǒng)調(diào)用) 。
poll
poll 也是操作系統(tǒng)提供的系統(tǒng)調(diào)用函數(shù) 。
int poll(struct pollfd *fds, nfds_tnfds, int timeout);
struct pollfd {
  intfd; /*文件描述符*/
  shortevents; /*監(jiān)控的事件*/
  shortrevents; /*監(jiān)控事件中滿(mǎn)足條件返回的事件*/
};
它和 select 的主要區(qū)別就是,去掉了 select 只能監(jiān)聽(tīng) 1024 個(gè)文件描述符的限制 。
epoll
epoll 是最終的大 boss,它解決了 select 和 poll 的一些問(wèn)題 。
還記得上面說(shuō)的 select 的三個(gè)細(xì)節(jié)么?
1. select 調(diào)用需要傳入 fd 數(shù)組,需要拷貝一份到內(nèi)核,高并發(fā)場(chǎng)景下這樣的拷貝消耗的資源是驚人的 。(可優(yōu)化為不復(fù)制)
2. select 在內(nèi)核層仍然是通過(guò)遍歷的方式檢查文件描述符的就緒狀態(tài),是個(gè)同步過(guò)程,只不過(guò)無(wú)系統(tǒng)調(diào)用切換上下文的開(kāi)銷(xiāo) 。(內(nèi)核層可優(yōu)化為異步事件通知)
3. select 僅僅返回可讀文件描述符的個(gè)數(shù),具體哪個(gè)可讀還是要用戶(hù)自己遍歷 。(可優(yōu)化為只返回給用戶(hù)就緒的文件描述符,無(wú)需用戶(hù)做無(wú)效的遍歷)
所以 epoll 主要就是針對(duì)這三點(diǎn)進(jìn)行了改進(jìn) 。
1. 內(nèi)核中保存一份文件描述符集合,無(wú)需用戶(hù)每次都重新傳入,只需告訴內(nèi)核修改的部分即可 。
2. 內(nèi)核不再通過(guò)輪詢(xún)的方式找到就緒的文件描述符,而是通過(guò)異步 IO 事件喚醒 。
【無(wú)法連接到internet怎么解決 無(wú)法連接到internet】3. 內(nèi)核僅會(huì)將有 IO 事件的文件描述符返回給用戶(hù),用戶(hù)也無(wú)需遍歷整個(gè)文件描述符集合 。
具體,操作系統(tǒng)提供了這三個(gè)函數(shù) 。
第一步,創(chuàng)建一個(gè) epoll 句柄
int epoll_create(int size);
第二步,向內(nèi)核添加、修改或刪除要監(jiān)控的文件描述符 。
int epoll_ctl(
  int epfd, int op, int fd, struct epoll_event *event);
第三步,類(lèi)似發(fā)起了 select() 調(diào)用
int epoll_wait(
  int epfd, struct epoll_event *events, int max events, int timeout);
使用起來(lái),其內(nèi)部原理就像如下一般絲滑 。
如果你想繼續(xù)深入了解 epoll 的底層原理,推薦閱讀飛哥的《圖解 | 深入揭秘 epoll 是如何實(shí)現(xiàn) IO 多路復(fù)用的!》,從 linux 源碼級(jí)別,一行一行非常硬核地解讀 epoll 的實(shí)現(xiàn)原理,且配有大量方便理解的圖片,非常適合源碼控的小伙伴閱讀 。
后記
大白話(huà)總結(jié)一下 。
一切的開(kāi)始,都起源于這個(gè) read 函數(shù)是操作系統(tǒng)提供的,而且是阻塞的,我們叫它 阻塞 IO 。

推薦閱讀