文件控制操作

简介: 文件控制操作

在实际应用中,经常会遇到多个程序同时操作一个文件的情况,专业术语为:文件共享,有时也称为竞态Linux 中通常采用的方式是对文件上锁,以解决对共享资源的竞争。


文件锁包括建议性锁强制性锁。建议性锁要求每个相关程序在访问文件之前检查是否有锁存在,并且尊重已有的锁。而强制性锁是由内核执行的锁,当程序对文件上锁并执行写入操作时,内核将阻止其他程序对该文件进行读写操作。采用强制性锁对性能的影响较大,每次读写操作内核都检查是否有锁存在


Linux 中,实现文件上锁的函数有 lockf()fcntl() ,其中 lockf() 函数用于对文件施加建议性锁,而 fcntl() 函数不仅可以施加建议性锁,还可以施加强制性锁。同时, fcntl() 函数还能对文件的某一记录上锁,也就是记录锁


记录锁又可以分为读取锁写入锁,其中读取锁又称为共享锁,多个同时执行的程序允许在文件的同一部分建立读取锁。而写入锁又称为排斥锁,在任何时刻只能有一个程序在文件的某个部分建立写入锁。显然,在文件的同一部分不能同时建立读取锁和写入锁。


fcntl() 函数具有丰富的功能,它可以对已打开的文件进行各种操作,不仅能够管理文件锁,还可以获取和设置文件相关标志位,以及复制文件描述符等。


语法如下:

#include <unistd.h>
#include <fcntl.h>
int fcntl(int fd, int cmd, .../* arg */);点击复制复制失败已复制


参数 fd文件描述符,参数 cmd 用来实现函数不同的功能。 cmd 功能设置如下所示:

cmd 功能
F_DUPFD 复制一个现存的描述符
F_GETFDF_SETFD 获取或设置文件描述符标记
F_GETFLF_SETFL 获得或设置文件状态标志
F_GETOWNF_SETOWN 获得或设置异步I/O所有权
F_GETLKF_SETLK 或 `F_SETLKW ` 获得或设置记录锁


其中, F_GETFLF_SETFL 用来获取或设置文件状态标志,即文件的打开和关闭中提到的 O_APPENDO_NONBLOCK 等标志位。如需设置,将值传入第三个参数。


F_GETOWNF_SETOWN 用来获取或设置接受 SIGIOSIGURG 信号的进程ID组ID


如果 cmd 和锁操作有关,则第三个参数的类型为 struct flock* ,其定义如下:

struct flock {
  ……
  short l_type;     /* Type of lock: F_RDLCK, F_WRLCK, F_UNLCK */
  short l_whence;   /* How to interpret l_start: SEEK_SET, SEEK_CUR, SEEK_END */
  off_t l_start;    /* Starting offset for lock */
  off_t l_len;      /* Number of bytes to lock */
  pid_t l_pid;      /* PID of process blocking our lock (F_GETLK only) */
}点击复制复制失败已复制


flock 结构体成员如下所示:

成员 含义
l_type F_RDLCK:读取锁(共享锁)
F_WRLCK:写入锁(排斥锁)
F_UNLCK:解锁
l_start 加锁区域在文件中的相对偏移量(字节),与l_whence值一起决定加锁区域的起始位置
l_whence SEEK_SET:加锁区域为文件的开始处
SEEK_CUR:加锁区域为文件的当前位置
SEEK_END:加锁区域为文件的末尾处
l_len 加锁区域的长度
l_pid 具有阻塞当前进程的锁,其持有的进程的进程号存放在l_pid中,仅由F_GETLK返回
目录
相关文章
|
3月前
|
存储 缓存 Unix
victoriaMetrics中的一些Sao操作
victoriaMetrics中的一些Sao操作
25 1
|
C++
c++一些简单操作
c++一些简单操作
74 0
|
分布式计算 网络协议 Ubuntu
系统通信方式操作
系统通信方式操作
74 0
系统通信方式操作
|
索引 Windows
ListControl操作
ListControl操作
79 0
|
SQL Java 数据库连接
MyBatisCRUD操作
MyBatisCRUD操作
C#编程-90:Hashtale相关操作
C#编程-90:Hashtale相关操作