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 //没有sleep,非阻塞,来不及输入 #define EAGAIN 11 /* Try again */ //在sleep的时候输入hello,回车送入IO缓冲区,等sleep醒来之后,read直接读走数据; |