前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >非阻塞IO

非阻塞IO

作者头像
二肥是只大懒蓝猫
发布2023-10-13 11:36:46
1740
发布2023-10-13 11:36:46
举报
文章被收录于专栏:热爱C嘎嘎热爱C嘎嘎

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

fcntl函数

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

函数原型如下:

代码语言:javascript
复制
#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,表示没有就绪。

使用代码简单实现非阻塞

代码语言:javascript
复制
#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;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • fcntl函数
  • 使用代码简单实现非阻塞
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档