I/O多路複用解析

  • 前言

其實這篇博客在很早前就開始寫了,但因爲時間原因,在草稿箱中封藏已久,今天將未完成的部分繼續續寫。

開始我對這個多路複用的名詞感到很好奇(在很多高效服務器中都用到了這個技術,如:IOCP、epoll),對於程序員來說讓自己困惑的東西怎麼能放過呢?於是我在網絡上尋找各種對這個名詞的解釋。


  • 什麼是I/O多路複用

這裏我舉一個不大形象又有點形象的栗子:

有一條不大不小的馬路,要想走這條路只有一個辦法,就是從A、B、C、D........(大門編號)這些大門進入,假設你有N個大門,當有人想要走你這條路的時候必須敲門(這是一個信號量),接收到這個信號後你便可以去打開這個大門,讓這個行人進入,隨後你又會關上這扇門(防賊哈哈哈),然後等待下一個敲門的人(因爲你不知道那扇門會有人敲門),併爲他開門。因爲你只是一個人(單線程),所以同時也只能打開一扇門。

栗子講完了,迴歸我們正題,所以所謂的I/O多路複用,其實就是單個線程通過記錄跟蹤每一個Sock(I/O流)的狀態來同時管理多個I/O流。下圖便是多路複用示意圖,左邊的那三個綠框其實就可以理解爲我們上面說的大門,而共享信道就是我們的馬路了,來自各個地方的人都需要經過這條路(也即爲是單線程的)。



                                                     上圖摘自百度百科


  • 實際運用

對於未使用IO多路複用的模型來說,同一個線程同時只能處理一個IO請求,如果有其他IO請求到來時只能等待。而對於IO多路複用模型來說則能夠實現在同一個線程內同時處理多個IO請求的目的。下面是使用select的方式(目前在linux下比較強大的還是使用epoll來實現)來實現多路複用的僞代碼:

{
    select(socket);
    while(1) {
        sockets = select();
        for(socket in sockets) {
            if(can_read(socket)) {
                read(socket, buffer);
                process(buffer);
            }
        }
    }
}

其中while循環前將socket添加到select監視中,然後在while內一直調用select獲取被激活的socket,一旦socket可讀,便調用read函數將socket中的數據讀取出來。


  • 參考文獻

https://www.zhihu.com/question/32163005

https://blog.csdn.net/baixiaoshi/article/details/48708347

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章