通常我們在設定介面是阻塞還是非阻塞的時候,有兩種方案:
(1)將檔案描述符設定為非阻塞式檔案描述符;
(2)通過傳遞特殊選項,讓介面本身以非阻塞方式呼叫。
乙個檔案描述符,預設都是阻塞io。
fcntl的函式原型如下:
fcntl可以改變已經開啟的檔案性質。針對cmd的值,fcntl能夠接受第三個引數arg(可變引數列表)。傳入的cmd的值不同,後面追加的引數也不相同。
fcntl函式有五種功能:
(1)複製乙個現有的描述符(cmd = f_dupfd);
(2)獲得/設定檔案描述符標記(cmd = fgetfd 或 fsetfd)
(3)獲得/設定檔案狀態標記(cmd = fgetfl 或 fsetfl)
(4)獲得/設定非同步i/o所有權(cmd = fgetown 或 fsetown)
(5)獲得/設定記錄鎖(cmd = fgetlk 或 fsetkw)
我們此處只是使用第三種功能,獲得/設定檔案狀態標記,這樣就可以將乙個檔案描述符設定為非阻塞。
基於fcntl,我們實現乙個setnoblock函式,將檔案描述符設定為非阻塞。
#include #includevoid setnoblock(int fd)
fcntl(fd,f_setfl,fl | o_nonblock);//再使用f_setfl將檔案描述符設定回去,設定回去的同時,加上乙個o_nonblock引數
return;
}
#include#include #include#includevoid setnoblock(int fd)
fcntl(fd,f_setfl,fl | o_nonblock);
return;
}int main();
ssize_t num = read(0,buf,sizeof(buf)-1);
if(num == -1 && errno == eagain)
printf("input:%s\n",buf);
}return 0;
}
這個程式裡的eagain的定義如下: 高階IO 非阻塞
一 設定檔案描述符標誌 設定檔案描述符標誌 void set fl int fd,int flags 二 清除檔案描述符標誌 清除檔案描述符標誌 void clr fl int fd,int flags 三 主函式 int main void clr fl stdout fileno,o nonbl...
阻塞I O,非阻塞I O
拿 socket舉例。當read資料時,如果這時沒有資料可讀,阻塞i o會一直等待有資料讀,資料從kernel copy 到socket的buffer後返回 非阻塞i o會立即返回,但如果有資料可讀,非阻塞i o也是等資料從kernel copy 到socket的buffer後返回。以上是阻塞與非阻...
78 高階IO之非阻塞IO
高階io是相對於檔案io說的 檔案io,就是讀寫檔案,一切皆是檔案 高階io要解決讀寫以外的情況 阻塞式 函式呼叫會被卡住 雖然會釋放cpu的使用權,但是 不會往下走 核心會在此處掛起,好多預設的程式都是阻塞式的,常見的阻塞式的函式,sleep,wait,pause等,阻塞式在多路io的時候會有問題...