1. 程式人生 > >非阻塞I/O

非阻塞I/O

低速系統呼叫是可能會使程序永遠阻塞的一類系統呼叫,他們包括下列呼叫:

1:如果某些檔案型別(例如管道,終端裝置和網路裝置)的資料並不存在,則讀操作可能會使呼叫者永遠阻塞.

2:如果資料被能被上訴童言型別的檔案接受(由於管道中無空間,網路流控制等),則寫操作也會使呼叫者永遠阻塞.

3:在某種條件發生之前,開啟某些型別的檔案會被阻塞(例如開啟一個終端裝置可能需要等到與之連線的調製解挑器應答;有例如在沒有其他程序以讀模式開啟的FIFO上用寫模式開啟FIFO,那麼也要等待).

4:對已經加上強制性記錄鎖的檔案進行讀,寫.

5:某些ioctl操作.

6:某些程序間通訊函式.


對於一個給定的描述符有兩種方法對其制定非阻塞I/O:

1:如果呼叫open獲得描述符,則可制定O_NONBLOCK標誌.

2:對於已經開啟的一個描述符,則可呼叫fcntl,有該函式開啟O_NONBLOCK檔案狀態標誌.


#include<stdio.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>

char buf[500000];
int main(){
    int ntowrite,nwrite;
    char *ptr;
    ntowrite=read(STDIN_FILENO,buf,sizeof(buf));
    fprintf(stderr,"read %d bytes\n",ntowrite);
    ptr=buf;
    fcntl(STDOUT_FILENO,F_SETFL,O_NONBLOCK);
    while(ntowrite>0){
        nwrite=write(STDOUT_FILENO,ptr,ntowrite);
        if(nwrite>0){
            fprintf(stderr,"write %d bytes\n",nwrite);
            ptr+=nwrite;
            ntowrite-=nwrite;
        }
    }
    fcntl(STDOUT_FILENO,F_SETFL,0);
    exit(0);
}

向終端輸出資料時,由於是慢速,會多次呼叫write函式.如果一下語句註釋掉,則是阻塞I/O.
fcntl(STDOUT_FILENO,F_SETFL,O_NONBLOCK);