非阻塞IO

文章介绍了fcntl函数在实现非阻塞IO中的作用,通过设置文件状态标志O_NONBLOCK,使得在数据未准备好时读取不阻塞。当errno为EAGAIN时,表明读取未就绪。示例代码展示了如何将标准输入设置为非阻塞并处理读取情况。
摘要由CSDN通过智能技术生成

本文分享的是非阻塞IO,其中包括fcntl函数,然后简单代码实现轮询标志输入输出。

fcntl函数

fcntl函数是一个用于控制文件描述符的系统调用,一个文件描述符, 默认都是阻塞IO。它能够实现文件描述符的各种操作,如复制文件描述符、修改文件状态标志、获取文件状态标志等。

函数原型如下:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );

参数说明:

  • fd:需要操作的文件描述符;
  • cmd:需要执行的操作命令;
  • arg:命令所需的参数,具体取决于操作命令。

传入的cmd的值不同, 后面追加的参数也不相同,fcntl函数有5种功能:

复制一个现有的描述符(cmd=F_DUPFD):该命令会复制一个文件描述符,并返回复制后的文件描述符。

 
获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)。

 
获得/设置文件状态标记(cmd=F_GETFL或F_SETFL)::该命令可以获取和修改文件的状态标志,如O_NONBLOCK、O_APPEND等。

 
获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)。

 
获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW)::该命令可以获取和修改文件的共享锁和独占锁。

用第三种功能, 获取/设置文件状态标记, 就可以将一个文件描述符设置为非阻塞。

在非阻塞的情况下读取数据,如果数据没有就绪,系统是以出错的形式返回(但并非出错),因此在次情况下,没有就绪和出错,使用的是相同的方式去标识。可以使用errno来区分,究竟是没有就绪还是出错。如果errno返回11,即EAGEIN==11,表示没有就绪。

使用代码简单实现非阻塞

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


void SetNonBlock(int fd)
{
  int f1 = fcntl(fd,F_GETFL);
  if(f1 < 0)
  {
    perror("fcntl");
    return;
  }

  fcntl(fd,F_SETFL,f1 | O_NONBLOCK);
}
int main()
{
  SetNonBlock(0);
  while(1)
  {
    char buffer[1024];
    ssize_t s = read(0,buffer,sizeof(buffer)-1);
    if(s > 0)
    {
      buffer[s]=0;
      write(1,buffer,strlen(buffer));
      printf("read success, s:%d,errno: %d\n",s,errno);
    }
    else{
        printf("read fail, s:%d,errno: %d\n",s,errno);
    }
    sleep(1);
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山雾隐藏的黄昏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值