国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux I/O多路復用詳解及實例

2019-11-02 16:25:10
字體:
來源:轉載
供稿:網友

Linux I/O多路復用

Linux中一切皆文件,不論是我們存儲在磁盤上的字符文件,可執行文件還是我們的接入電腦的I/O設備等都被VFS抽象成了文件,比如標準輸入設備默認是鍵盤,我們在操作標準輸入設備的時候,其實操作的是默認打開的一個文件描述符是0的文件,而一切軟件操作硬件都需要通過OS,而OS操作一切硬件都需要相應的驅動程序,這個驅動程序里配置了這個硬件的相應配置和使用方法。Linux的I/O分為阻塞I/O,非阻塞I/O,I/O多路復用,信號驅動I/O四種。對于I/O設備的驅動,一般都會提供關于阻塞和非阻塞兩種配置。我們最常見的I/O設備之一--鍵盤(標準輸入設備)的驅動程序默認是阻塞的。

多路復用就是為了使進程能夠從多個阻塞I/O中獲得自己想要的數據并繼續執行接下來的任務。其主要的思路就是同時監視多個文件描述符,如果有文件描述符的設定狀態的被觸發,就繼續執行進程,如果沒有任何一個文件描述符的設定狀態被觸發,進程進入sleep

多路復用的一個主要用途就是實現"I/O多路復用并發服務器",和多線程并發或者多進程并發相比,這種服務器的系統開銷更低,更適合做web服務器。

阻塞I/O

阻塞I/O,就是當進程試圖訪問這個I/O設備而這個設備并沒有準備好的時候,設備的驅動程序會通過內核讓這個試圖訪問的進程進入sleep狀態。阻塞I/O的一個好處就是可以大大的節約CPU時間,因為一旦一個進程試圖訪問一個沒有準備好的阻塞I/O,就會進入sleep狀態,而進入sleep狀態的進程是不在內核的進程調度鏈表中,直到目標I/O準備好了將其喚醒并加入調度鏈表,這樣就可以節約CPU時間。當然阻塞I/O也有其固有的缺點,如果進程試圖訪問一個阻塞I/O,但是否訪問成功并不對接下來的任務有決定性影響,那么直接使其進入sleep狀態顯然會延誤其任務的完成。

典型的默認阻塞IO有標準輸入設備,socket設備,管道設備等,當我們使用gets(),scanf(),read()等操作請求這些IO時而IO并沒有數據流入,就會造成進程的sleep。

假設一個進程希望通過三個管道中任意一個中讀取數據并顯示,偽代碼如下

read(pipe_0,buf,sizeof(buf));    //sleepprint buf;read(pipe_1,buf,sizeof(buf));print buf;read(pipe_2,buf,sizeof(buf));print buf;

由于管道是阻塞I/O,所以如果pipe_0沒有數據流入,進程就是在第一個read()處進入sleep狀態而即使pipe_1和pipe_2有數據流入也不會被讀取。

如果我們使用下述代碼重新設置管道的阻塞屬性,顯然,如果三個管道都沒有數據流入,那么進程就無法獲得請求的數據而繼續執行,倘若這些數據很重要(所以我們才要用阻塞I/O),那結果就會十分的糟糕,改為輪詢卻又大量的占據CPU時間。

int fl = fcntl(pipe_fd, F_GETFL);

fcntl(pipe_fd, F_SETFL, fl | O_NONBLOCK);

如何讓進程同時監視三個管道,其中一個有數據就繼續執行而不會sleep,如果全部沒有數據流入再sleep,就是多路復用技術需要解決的問題。

非阻塞I/O

非阻塞I/O就是當一個進程試圖訪問一個I/O設備的時候,無論是否從中獲取了請求的數據都會返回并繼續執行接下來的任務。,但非常適合請求是否成功對接下來的任務影響不大的I/O請求。但如果訪問一個非阻塞I/O,但這個請求如果失敗對進程接下來的任務有致命影響,最粗暴的就是使用while(1){read()}輪詢。顯然,這種方式會占用大量的CPU時間。

select機制

select是一種非常"古老"的同步I/O接口,但是提供了一種很好的I/O多路復用的思路

模型

fd_set   //創建fd_set對象,將來從中增減需要監視的fdFD_ZERO()  //清空fd_set對象FD_SET()  //將一個fd加入fd_set對象中 select()  //監視fd_set對象中的文件描述符pselect()  //先設定信號屏蔽,再監視FD_ISSET() //測試fd是否屬于fd_set對象FD_CLR()  //從fd_set對象中刪除fd
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 六安市| 陕西省| 重庆市| 宕昌县| 锡林郭勒盟| 龙川县| 游戏| 吴江市| 汉源县| 衡南县| 临武县| 都江堰市| 台东县| 花莲市| 三都| 白朗县| 屏山县| 炎陵县| 林芝县| 乡宁县| 汉源县| 渭源县| 湖口县| 札达县| 共和县| 莫力| 星子县| 德令哈市| 资讯 | 南宫市| 库尔勒市| 亚东县| 育儿| 大安市| 茌平县| 南康市| 新营市| 兴山县| 正宁县| 奇台县| 安义县|