1.文件控制 fcntl()中的参数cmd汇总
命令字cmd | 变参arg | 含义 |
F_DUPFD | long arg | 将 fd 复制为不小于arg 的最小未用的文件描述符,通 过返回值返回。 |
F_DUPFD_CLOEXE C | long arg | 作 用跟 F_DUPFD一样 , 但 新 复 制 的 描 述 符 的 FD_CLOEXEC 状态会被设置为 1。 |
F——GETFD | void | 获取 FD_CLOEXEC 状态。 |
F_SETFD | long arg | 设置 FD_CLOEXEC 状态,若该状态位为 0 则意味着该 fd 在程序执行 execve( )加载新代码的时候将保持有 效,否则该 fd 在新代码执行时将被关闭。 |
F_GETFL | void | 获取 status 状态。 |
F_SETFL | long arg | 设置 status 状态。 在 Linux 中,以下选项不可设置: O_RDONLY O_WRONLY O_RDWR O_CREAT O_EXCL O_NOCTTY O_TRUNC 以下的选项可以设置: O_APPEND O_ASYNC O_DIRECT O_NOATIME O_NONBLOCK |
F_SETLK | ①struct flock *arg | 将 arg.l_type 设置为以下值意味着加锁: FD_RDLCK FD_WRLCK 将 l_type 设置为以下值意味着解锁: FD_UNLCK 如果当前区域已经有冲突的锁存在,那么将立即返回 -1,且 errno 将被设置为 EACCES 或者 EAGAIN。 |
F_SETLKW | struct flock *arg | 跟 F_SETLK 一样,但在冲突的情况下将会阻塞等待。 |
② F_GETLK | struct flock *arg | 用 arg 中的信息检查是否有冲突,如果无冲突,则将 arg.l_type 设置为 FD_UNLCK,别的成员保持不变。 如果有冲突,则 arg 将会储存当前冲突的锁的相关信 息。 |
F_GETOWN | void | 获取收到由 fd 输入或输出状态改变而触发的信号 SIGIO 和 SIGURG 的进程或进程组 ID 。进程 ID 用正 整数表示,进程组 ID 用负整数表示。 |
F_SETOWN | long arg | 设置接收由 fd 输入或输出状态改变而触发的信号 SIGIO 和 SIGURG 的进程或进程组 ID 为 arg。进程 ID 用正整数表示,进程组 ID 用负整数表示。 |
③ F_GETOWN_EX | struct f_woner_ex *arg | 作用同 F_GETOWN,但还能获取线程的 TID,且只能 适用于 Linux-2.6.32 及以后的版本。 |
F_SETOWN _EX | struct f_woner_ex *arg | 作用同 F_SETOWN,但还能设置线程的 TID,且只能 适用于 Linux-2.6.32 及以后的版本。 |
F_GETSIG | void | 获取由fd 输入或输出状态改变而触发的信号。 |
F_SETSIG | long arg | 设置由fd 输入或输出状态改变而触发的信号。 |
F_GETPIPE_SZ | void | 获取管道文件缓冲区的大小 |
F_GETPIPE_SZ | long arg | 设置管道文件缓冲区的大小为 arg 。arg 必须介于 Linux 内 存 页 大 小 和 系 统 支 持 的 最 大 尺 寸 ( 见 /proc/sys/fs/pipe-size-max) 之间。 |
注:① 该结构体的内部成员至少有:
struct flock
{
short l_type; // 记录锁的类型:FD_RDLCK、FD_WRLCK、FD_UNLCK
short l_whence; // 基准点:SEEK_SET、SEEK_CUR、SEEK_END
off_t l_start; // 锁区域相当于基准点的偏移量,可以为负整数
off_t l_len; // 锁区域长度
pid_t l_pid; // 在 F_GETLK 命令字下可以获得持有锁资源的进程 PID
};
② A) 对一个文件必须有可读或者可写权限,才能分别对该文件加读记录锁和写记录 锁。另外,由于缓冲区的原因,应避免在涉及记录锁的场合使用标准 IO (详见下一小节) , 而应该用系统 IO 函数代替。
B) 除了可以使用 F_UNLCK 来释放记录锁之外,进程的退出也会自动释放记录锁。
C) 记录锁不会被通过 fork( )系统调用创建出来的子进程继承,但可以在进程执行 execve( )加载新代码之后继续保持。
D) 记录锁可以是协商性的,也可以是强制性的,缺省是协商性的。协商性的记录 锁不对文件本身做任何处理,因此只能用于相互协作的进程之间。强制性的记录锁将会作用 于文件本身,使得任何进程在读写已经加了锁的文件的相关区域时阻塞或者发生错误,强制 性的记录锁要求在挂载文件系统时使用“-o mand”选项或者使用“MS_MANDLOCK”参数, 且要求去掉该文件的组执行权限并且设置其 setgid。在 Linux 系统中,强制性的记录锁尚存 BUG 未解决,是不可用的。
③ 结构体 f_owner_ex 的定义如下:
struct f_owner_ex
{
int type; // ID 的类型:F_OWNER_TID、F_OWNER_PID 和 F_OWNER_PGRP
pid_t pid; // 正整数为线程 ID、进程 ID,负整数为进程组 ID
};
2.内存映射mmap函数中参数flags汇总
当有多个进程同时映射了这块内存时,该参数可以决定在某一个进程 内使映射内存的数据发生变更是否影响其他进程,也可以决定是否影 响其对应的文件数据。
以下两个选项互斥:
MAP_SHARED : 所有的同时映射了这块内存的进程对数据的变更均 可见,而且数据的变更会直接同步到对应的文件 (有时可能还需要调 用 msync( )或者 munmap( )才会真正起作用) 。
MAP_PRIVATE : 与 MAP_SHARED 相反,映射了这块内存的进程对数 据的变更对别的进程不可见,也不会影响其对应的文件数据。
以下选项可以位或累加:
MAP_32BIT :在早期的 64 位 x86 处理器上,设置这个选项可以将线程 的栈空间设置在最低的 2GB 空间附近,以便于上下文切换时得到更好 的表现性能,但现代的64 位 x86 处理器本身已经解决了这个问题, 因此这个选项已经被弃用了。
MAP_ANON :等同于 MAP_ANONYMOUS,已弃用。
MAP_ANONYMOUS :匿名映射。该选项使得该映射内存不与任何文件 关联,一般来讲参数 fd和 offset 会被忽略 (但是可移植性程序需要将 fd 设置为-1) 。另外,这个选项必须跟 MAP_SHARED 一起使用。
MAP_DENYWRITE :很久以前,这个选项可以使得试图写文件fd 的进 程收到一个 ETXTBUSY 的错误,但是这很快成为所谓“拒绝服务”攻 击的来源,因此现在这个选项也被弃用了。
MAP_FIXED :该选项使得映射内存的起始地址严格等于参数 addr 而不 仅仅将 addr 当做参考值,这必须要求 addr 是页内存大小的整数倍, 由于可移植性的关系,这个选项一般不建议设置。
MAP_GROWSDOWN :使得映射内存向下增长,即返回的是内存的最高 地址,一般用于栈。
MAP_HUGETLB :使用“大页”来分配映射内存。关于“大页”请参考 内核源代码中的 Documentation/vm/hugetlbpage.txt。
MAP_NONBLOCK :该选项必须与 MAP_POPULATE 一起使用,表示不 进行“预读”操作。这使得选项 MAP_POPULATE 变得毫无意义,相信 未来的某一天这两个选项会被修改。
MAP_NORESERVE :该选项旨在不为这块映射内存使用“交换分区”, 也就是说当物理内存不足时,操作映射内存将会收到 SIGSEGV,而如 果允许使用交换分区则可以保证不会因为物理内存不足而出现这个错误。
MAP_POPULATE :将页表映射至内存中,如果用于文件映射,该选项 会导致“预读”的操作,因而在遇到页错误的时候也不会被阻塞。
MAP_STACK :在进程或线程的栈中映射内存。
MAP_UNINITIALIZED :不初始化匿名映射内存。