非阻塞I/O
阿新 • • 發佈:2018-12-16
低速系統呼叫是可能會使程序永遠阻塞的一類系統呼叫,他們包括下列呼叫:
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);