IO阻塞非阻塞. select

來源:互聯網
上載者:User

五種I/O 模式——阻塞(預設IO模式),非阻塞(常用語管道),I/O多工(IO多工應用情境),訊號I/O,非同步I/O

Linux下的I/O操作預設是阻塞I/O,即open和socket建立的I/O都是阻塞I/O

非阻塞 I/O (可以通過fcntl或者open時使用O_NONBLOCK參數,將fd設定為非阻塞的I/O)

//非阻塞模式,相當於告訴了系統核心: “當我請求的I/O 操作不能夠馬上完成,請馬上返回一個錯誤給我。”#include <sys/time.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <assert.h>#include <errno.h>int main (){    int keyboard;    int ret,i;    char c;    keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK); //非阻塞    //keyboard = open("/dev/tty",O_RDONLY);     assert(keyboard>0);    while(1) {        if((i = read(keyboard,&c,1)) != -1){            if('\n'==c){                continue;            }            printf("Input is %c\n",c);            sleep(3);            if ('q'==c){                break;            }        }else if(i == -1){            perror("緩衝區沒有資料可讀\n");                sleep(3);        }else{            printf("%s\n", "Timeout  逾時");            sleep(3);        }    }}

運行結果:  # (如果使用者沒有輸入資料)

緩衝區沒有資料可讀
: Resource temporarily unavailable
緩衝區沒有資料可讀
: Resource temporarily unavailable
1           #輸入資料
Input is 1
q
Input is q

    //預設是阻塞狀態    //keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK); //非阻塞    keyboard = open("/dev/tty",O_RDONLY); 

運行結果:# (如果使用者沒有輸入資料)  read()不會返回,阻塞在那裡了。

1          
#輸入資料
Input is 1
q
Input is q

阻塞方式block,就是進程或是線程執行到這些函數時必須等待某個事件的發生,如果事件沒有發生,進程或線程就被阻塞,函數不能立即返回。使用Select就可以完成非阻塞non-block,就是進程或線程執行此函數時不必非要等待事件的發生,一旦執行肯定返回,以傳回值的不同來反映函數的執行情況,如果事件發生則與阻塞方式相同,若事件沒有發生則返回一個代碼來告知事件未發生,而進程或線程繼續執行,所以效率較高。select能夠監視我們需要監視的檔案描述符的變化情況。

int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

1、ndfs:select中監視的檔案控制代碼數,一般設為要監視的檔案中的最大檔案號加一。
2、rdfds:select()監視的可讀檔案控制代碼集合,當rdfds映象的檔案控制代碼狀態變成可讀時系統告訴select函數返回。
這個集合中有一個檔案可讀,select就會返回一個大於0的值,表示有檔案可讀,
如果沒有可讀的檔案,則根據timeout參數再判斷是否逾時,
若超出timeout的時間,select返回0,若發生錯誤返回負值,
可以傳入NULL值,表示不關心任何檔案的讀變化;
3、wtfds: select()監視的可寫檔案控制代碼集合
4、exfds:select()監視的異常檔案控制代碼集合,當exfds映象的檔案控制代碼上有特殊情況發生時系統會告訴select函數返回。
5、timeout:select()的逾時結束時間。
這個參數它使select處於三種狀態,
第一,若將NULL以形參傳入,即不傳入時間結構,就是將select置於阻塞狀態,
一定等到監視檔案描述符集合中某個檔案描述符發生變化為止;
第二,若將時間值設為0秒0毫秒,就變成一個純粹的非阻塞函數,不管檔案描述符是否有變化,
都立刻返回繼續執行,檔案無變化返回0,有變化返回一個正值;
第三,timeout的值大於0,這就是等待的逾時時間,即select在timeout時間內阻塞,
逾時時間之內有事件到來就返回了,否則在逾時後不管怎樣一定返回,傳回值同上述

6、RETURN VALUE
       On success, select() and pselect() return the number of file descriptors  contained  in  the
       three  returned  descriptor sets (that is, the total number of bits that are set in readfds,
       writefds, exceptfds) which may be zero if the timeout expires  before  anything  interesting
       happens.   On  error,  -1  is returned, and errno is set appropriately; the sets and timeout
       become undefined, so do not rely on their contents after an error.

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);樣本:

#include <sys/time.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <assert.h>int main (){    int keyboard;    int ret,i;    char c;    fd_set readfd;    struct timeval timeout;    keyboard = open("/dev/tty",O_RDONLY | O_NONBLOCK); //非阻塞    assert(keyboard>0);    while(1) {        timeout.tv_sec=2;        timeout.tv_usec=0;        FD_ZERO(&readfd);        FD_SET(keyboard,&readfd);        ret=select(keyboard+1,&readfd,NULL,NULL,&timeout);        if(FD_ISSET(keyboard,&readfd)) {            i=read(keyboard,&c,1);            if('\n'==c){                continue;            }            printf("Input is %c\n",c);            if ('q'==c){                break;            }        }else{            printf("%s\n", "Timeout  逾時");        }    }}

運行結果:

Timeout  逾時
q
Input is q

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.