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

相关推荐
安於宿命2 分钟前
【Linux】简易版shell
linux·运维·服务器
shymoy2 分钟前
Radix Sorts
数据结构·算法·排序算法
追梦不止~9 分钟前
Docker常用命令+详解
运维·docker·容器
风影小子11 分钟前
注册登录学生管理系统小项目
算法
黑龙江亿林等保13 分钟前
深入探索哈尔滨二级等保下的负载均衡SLB及其核心算法
运维·算法·负载均衡
黄小耶@14 分钟前
linux常见命令
linux·运维·服务器
叫我龙翔15 分钟前
【计网】实现reactor反应堆模型 --- 框架搭建
linux·运维·网络
lucy1530275107916 分钟前
【青牛科技】GC5931:工业风扇驱动芯片的卓越替代者
人工智能·科技·单片机·嵌入式硬件·算法·机器学习
古驿幽情17 分钟前
CentOS AppStream 8 手动更新 yum源
linux·运维·centos·yum
BillKu18 分钟前
Linux(CentOS)安装 Nginx
linux·运维·nginx·centos