c/c++ 阻塞和非阻塞,fcntl应用

调用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);
  }
}

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

相关文章
相关标签/搜索