• 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 ",ret);
            printf("errno=%d ",errno);
            printf("buf=%s ",buf);
            return 0;
    }
    //在非阻塞情况下,读取对应的描述符,如果缓冲区为空,返回值为-1,errno为 EAGAIN
      //没有sleep,非阻塞,来不及输入
    #define  EAGAIN  11         /* Try again */


     //在sleep的时候输入hello,回车送入IO缓冲区,等sleep醒来之后,read直接读走数据;




  • 相关阅读:
    Elasticsearch安装中文分词器IK
    Docker安装ElasticSearch
    Docker安装
    Docker安装EOS
    Docker更改容器端口映射
    BoltDB 一个简单的纯 Go key/value 存储
    go语言 robfig/cron包 实现定时 调用
    GitHub 添加 SSH keys
    Android 端外推送到底有多烦?
    Nats的消息通信模型
  • 原文地址:https://www.cnblogs.com/meihao1203/p/8655335.html
Copyright © 2020-2023  润新知