調用open函數時,能夠指定打開的文件描述符是以阻塞方式仍是以非阻塞方式。
阻塞概念:read函數在讀設備或者管道,或者socket的時候,默認是阻塞的,也就是說,對方若是沒有發送數據過來,則read函數就會一直等待數據過來,從代碼的角度來講,就是read函數後面的代碼不會被執行。
非阻塞概念:read函數在讀設備或者管道,或者socket的時候,對方若是沒有發送數據過來,read函數也會當即返回,從代碼的角度來講,就是read函數後面的代碼會立刻被執行。c++
非阻塞方式打開:微信
int fd = open("/dev/tty", O_RDWR|O_NONBLOCK);
阻塞方式打開:socket
int fd = open("/dev/tty", O_RDWR);
標準輸入輸出和錯誤,實際使用的文件是:/dev/tty,因此下面的例子用這個文件演示。
當用非阻塞的時候,若是沒有read到,函數不會等待,會當即返回,返回值是【-1】,這時errno的值爲【11】,用perror打印出來的信息是【Resource temporarily unavailable】
例子:函數
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main(int argc, char* argv[]){ int fd = open("/dev/tty", O_RDWR|O_NONBLOCK); char buf[256]; while(1){ int ret = read(fd, buf, sizeof buf); if(ret < 0){ perror("read:"); printf("ret :%d\n", ret); } printf("buf is:%s", buf); printf("haha\n"); } }
除了使用【O_NONBLOCK】外,還能夠使用fcntl函數,原型以下:學習
#include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); F_GETFD (void) Return (as the function result) the file descriptor flags; arg is ignored. F_SETFD (int) Set the file descriptor flags to the value specified by arg.
例子:code
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdio.h> int main(int argc, char* argv[]){ int fd = open("/dev/tty", O_RDWR); //先取得fd的flag int flags = fcntl(fd, F_GETFL); //再在原來fd的flag的基礎上,設置上O_NONBLOCK flags |= O_NONBLOCK; //讓新的flag生效 fcntl(fd, F_SETFL, flags); char buf[256]; while(1){ int ret = read(fd, buf, sizeof buf); if(ret < 0){ perror("read:"); printf("ret :%d\n", ret); } printf("buf is:%s", buf); printf("haha\n"); sleep(1); } }