fcntl 改变描述符属性

fcntl函数可以改变已打开的文件描述符性质: 要让阻塞函数不阻塞还能读写内容,就要在之前往缓冲区里放内容,这样当执行到改为非阻塞的函数的时候就可以直接读,不用阻塞等待;
eg:     sleep(2);   read(0,buf,sizeof(buf));
#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* arg */ );    //cmd的值确定第三个参数要不要填,填什么
参数fd  代表欲设置的文件描述符。
参数cmd 代表打算操作的指令, 用到的以下几种情况:


F_GETFL 取得文件描述词状态旗标,此旗标为open()的参数flags。第三个参数不用写
F_GETFL (void)   Get the file access mode and the file status flags; arg is ignored.
              
F_SETFL 设置文件描述词状态旗标,参数arg为新旗标,但只允许O_APPEND、O_NONBLOCK和O_ASYNC位的改变,其他位的改变将不受影响。
F_SETFL (int)    这些宏定义都是成功返回0,失败返回-1;  括号里面的类型表示arg要传参的参数类型
描述符都是有属性的,默认是阻塞属性;可以修改为非阻塞,这样描述符读写的时候就不会卡住
在非阻塞情况下,读取对应的描述符,如果缓冲区为空,返回值为-1,errno为 EAGAIN


read.c

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
void change_noblock(int fd)
{
        int status;
        status=fcntl(fd,F_GETFL);   //获取描述符的状态
        status=status|O_NONBLOCK;   //描述符状态加上非阻塞状态
        int ret=fcntl(fd,F_SETFL,status);
        if(-1==ret)
        {
                perror("fcntl");
                return;
        }
}
//标准输入改为非阻塞
int main()
{
        char buf[128]={0};
        change_noblock(0);
        //sleep(2);      //睡眠两秒,才有时间来输入数据
        int ret=read(0,buf,sizeof(buf));
        printf("ret=%d\n",ret);
        printf("errno=%d\n",errno);
        printf("buf=%s\n",buf);
        return 0;
}
//在非阻塞情况下,读取对应的描述符,如果缓冲区为空,返回值为-1,errno为 EAGAIN
we90h3x2VKu9QAAAABJRU5ErkJggg==  //没有sleep,非阻塞,来不及输入
#define  EAGAIN  11         /* Try again */


6b+39iF6R3E1GlvzQiMiOyOGv2cjzFg0p5KNmNlzdnG48nZfmz1VX0njNxl+7jiNypcvdL++J+8NlztUR85RRt6EF17f9N2ZXETjfLzNah7gtn6hLURR9wEIOLETZyoJm5aPsEtAwDeWTw4fvyoc73PQwKAafwf7k0vh7GhdK8AAAAASUVORK5CYII= //在sleep的时候输入hello,回车送入IO缓冲区,等sleep醒来之后,read直接读走数据;




转载于:https://www.cnblogs.com/meihao1203/p/8655335.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值