fcntl 改变描述符属性

时间:2024-04-14 17:42:45

body, table{font-family: 微软雅黑; font-size: 10pt}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

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
fcntl 改变描述符属性#define  EAGAIN  11         /* Try again */

fcntl 改变描述符属性