Linux中的高级IO函数(三)fcntl

Linux提供了很多高级的I/O函数。它们并不像Linux基础I/O函数(比如open和read)那么常用(编写内核模块时一般要实现这些I/O函数),但在特定的条件下却表现出优秀的性能。这些函数大致分为三类:

用于创建文件描述符的函数,包括pipe、socketpair、dup/dup2函数。

用于读写数据的函数,包括readv/writev、sendfile、mmap/munmap、splice和tee函数。

用于控制I/O行为和属性的函数,包括fcntl函数。

本节接着介绍第三类

一、fcntl函数

fcntl函数全称是 file control 。该函数提供了对文件描述符的各种控制操作。另外一个常见的控制文件描述符属性和行为的系统调用是ioctl,而且ioctlfcntl能够执行更多的控制。但是,对于控制文件描述符常用的属性和行为,fcntl函数是由POSIX规范指定的首选方法。

c 复制代码
#include <fcntl.h>

int fcntl(int fd, int cmd,  ...);
  • fd参数是被操作的文件描述符

  • cmd参数指定执行何种类型的操作

下面是一些常见的操作

cmd 含义 第三个参数类型 成功时返回值
F_DUPFD 复制文件描述符 int 复制的新文件描述符
F_GETFD 获取文件描述符标志 文件描述符标志位(整数)
F_SETFD 设置文件描述符标志 int 0(成功)或 -1(失败)
F_GETFL 获取文件状态标志 文件状态标志位(整数)
F_SETFL 设置文件状态标志 int 0(成功)或 -1(失败)
F_GETLK 获取记录锁 struct flock * 0(无冲突)或 -1(失败)
F_SETLK 设置记录锁 const struct flock * 0(成功)或 -1(失败)
F_SETLKW 设置记录锁(阻塞版本) const struct flock * 0(成功)或 -1(失败)
F_GETOWN 获取异步I/O所有权 所有权的进程ID(整数)
F_SETOWN 设置异步I/O所有权 pid_t 0(成功)或 -1(失败)
F_GETLK64 获取记录锁(64位版本) struct flock64 * 0(无冲突)或 -1(失败)
F_SETLK64 设置记录锁(64位版本) const struct flock64 * 0(成功)或 -1(失败)
F_SETLKW64 设置记录锁(阻塞版本,64位版本) const struct flock64 * 0(成功)或 -1(失败)
F_GETSIG 获取信号 信号值(整数)
F_SETSIG 设置信号 int 0(成功)或 -1(失败)
F_GETLEASE 获取文件租约状态 租约状态(整数)
F_SETLEASE 设置文件租约 int 0(成功)或 -1(失败)
F_NOTIFY 监视文件状态变化 int 0(成功)或 -1(失败)
F_GETPIPE_SZ 获取管道容量 管道容量(整数)
F_SETPIPE_SZ 设置管道容量 int 0(成功)或 -1(失败)
F_GET_SEALS 获取文件封印状态 文件封印状态(整数)
F_ADD_SEALS 添加文件封印 unsigned int 0(成功)或 -1(失败)
F_GET_RW_HINT 获取读写优化提示 读写优化提示(整数)
F_SET_RW_HINT 设置读写优化提示 unsigned int 0(成功)或 -1(失败)
F_GET_FILE_RW_HINT 获取文件读写优化提示 读写优化提示(整数)
F_SET_FILE_RW_HINT 设置文件读写优化提示 unsigned int 0(成功)或 -1(失败)
F_GETLKPID 获取记录锁并返回占有者的进程ID struct flock * 占有者的进程ID(整数)或 -1(失败)
F_OFD_GETLK 获取OFD记录锁 struct flock * 0(无冲突)或 -1(失败)
F_OFD_SETLK 设置OFD记录锁 const struct flock * 0(成功)或 -1(失败)
F_OFD_SETLKW 设置OFD记录锁(阻塞版本) const struct flock * 0(成功)或 -1(失败)

在常见的编程中,fcntl函数通常用来将一个文件描述符设置为非阻塞的。

c 复制代码
int setnonblocking(int fd) {
	/* 获取文件描述符旧的状态标志 */
    int old_option=fcntl(fd,F_GETFL);
    /* 设置非阻塞标志 */
    int new_option=old_option|O_NONBLOCK;
    /* 写入设置 */
    fcntl(fd,F_SETFL,new_option);
    /* 返回文件描述符旧的状态标志,以便日后恢复该状态标志 */
    return old_option;
}

此外,SIGIOSIGURG这两个信号与其他Linux信号不同,它们必须与某个文件描述符相关联方可使用:当被关联的文件描述符可读或可写时,系统将触发SIGIO信号;当被关联的文件描述符(而且必须是一个socket)上有带外数据可读时,系统将触发SIGURG信号。将信号和文件描述符关联的方法,就是使用fcntl函数为目标文件描述符指定宿主进程或进程组,那么被指定的宿主进程或进程组将捕获这两个信号。

相关推荐
一只码代码的章鱼27 分钟前
粒子群算法 笔记 数学建模
笔记·算法·数学建模·逻辑回归
小小小小关同学27 分钟前
【JVM】垃圾收集器详解
java·jvm·算法
圆圆滚滚小企鹅。32 分钟前
刷题笔记 贪心算法-1 贪心算法理论基础
笔记·算法·leetcode·贪心算法
努力的小T33 分钟前
基于 Bash 脚本的系统信息定时收集方案
linux·运维·服务器·网络·云计算·bash
Kacey Huang42 分钟前
YOLOv1、YOLOv2、YOLOv3目标检测算法原理与实战第十三天|YOLOv3实战、安装Typora
人工智能·算法·yolo·目标检测·计算机视觉
夜光小兔纸1 小时前
Oracle 普通用户连接hang住处理方法
运维·数据库·oracle
梓懿lwh1 小时前
vim的介绍
linux·编辑器·vim
eguid_11 小时前
JavaScript图像处理,常用图像边缘检测算法简单介绍说明
javascript·图像处理·算法·计算机视觉
带多刺的玫瑰1 小时前
Leecode刷题C语言之收集所有金币可获得的最大积分
算法·深度优先
爱敲代码的边芙1 小时前
Linux:信号的保存[2]
linux·运维·服务器