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函数为目标文件描述符指定宿主进程或进程组,那么被指定的宿主进程或进程组将捕获这两个信号。

相关推荐
2401_872418781 小时前
算法入门:数据结构-堆
数据结构·算法
三十..2 小时前
Ceph 三大存储接口深度实践与数据保护指南
运维·ceph
9分钟带帽2 小时前
linux_系统开机自动执行shell脚本
linux·服务器
xwz小王子3 小时前
手术机器人登上Science Robotics:2毫米纤细手臂,从3厘米切口完成腰椎神经减压
算法·机器人
蝶豆花3 小时前
基于商城系统的功能,自动化,性能-测试报告
运维·自动化
袋鼠云数栈3 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
黎阳之光3 小时前
视频孪生智护供水生命线:黎阳之光赋能医疗与园区水务高质量升级
运维·物联网·算法·安全·数字孪生
志栋智能4 小时前
AI驱动无代码:降低巡检超自动化的门槛
大数据·运维·网络·人工智能·自动化
Black蜡笔小新4 小时前
自动化AI算法训练服务器DLTM制造业AI质检工作站助力制造业实现AI智检
人工智能·算法·自动化
嵌入式小能手4 小时前
飞凌嵌入式ElfBoard-进程间的通信之命名管道
linux·服务器·算法