[13]APUE:(文件)记录锁

[a] 概念

  • 建议锁:在遵循相同记录锁规则的进程间生效,通常用于保证某个程序自身多个进程间的数据一致性
  • 强制锁:意在保证所有进程间的数据一致性,但不一定有效;如不能应对先 unlink 后建立同名副本的行为

[b] fcntl

#include <fcntl.h>
int fcntl(int fd, int cmd, struct flock *flockp) //出错返回 -1 
struct flock {
    short    l_type; //锁类型:F_RDLCK / F_WRLCK / F_UNLCK
    short    l_whence; //偏移基准:SEEK_SET / SEEK_CUR / SEEK_END
    off_t    l_start; //相对于 l_whence 的偏移量(byte)
    off_t    l_len; //加锁区域的长度(byte)
    pid_t    l_pid; //仅对 F_GETLK 有意义,获取当前拥有锁的进程 ID
} 
  • 操纵记录锁时,fcntl 的第三个参数是一个指向 flock 结构体的指针
  • cmd 可以为 F_GETLK / F_SETLK / F_SETLKW,分别用于获取文件的锁状态、设置锁(非阻塞)、设置锁(阻塞)
  • struct flock 中 l_len 字段若设置为 0,表示区段范围动态扩展至文件末尾, 如加锁之后在文件末尾追加的任何数据将被锁定,若设置为 -1,表示 l_start 之前的所有数据;l_type 字段设置为 F_UNLCK 时用于清除指定的锁
  • 同一进程对同一文件的同一区段重复加锁,新锁会取代旧锁,旧锁即时失效
  • 执行 F_GETLCK 时,目前的锁状态信息会被写入 flock 结构体中

[c] 死锁

  • 两个进程相互等待对方持有的锁且不释放自己锁定的资源时,会形成死锁
  • 现代的操作系统会自动解开死锁,通常是使其中一个进程的出错返回,而另一个进程成功获得锁,但不能确定一定是哪个进程获得锁

[d] 锁的隐含继承和释放

  • 进程终止时,其所建立的锁会全部释放
  • 当多个文件描述符关联到同一个文件时,其中任何一个文件描述符关闭,将会导致锁被释放
  • fork 之后的子进程不继承父进程的锁,exec 之后的进程继承原进程的锁(若设置了 close-on-exec 标志,则不继承)

[e] 在文件末尾加锁

  • 由于文件末尾的位置会随着追加数据而变化,故解锁时需要注意指定正确的范围

[f] 锁的组合与分裂

  • 若对两个已加锁的区段中间的部分全部加锁,则此三部分会组合成一个锁
  • 若对已经加锁的区段中间的一部分进行解锁,则原锁会被自动分裂为两个锁
时间: 2025-01-15 22:58:19

[13]APUE:(文件)记录锁的相关文章

文件记录锁的释放

引言:apue中提到文件记录锁的释放中的两条规则:当进程终止的时候,进程在文件上建立的记录锁会全部释放:当关闭文件,执行close(fd)函数的时候,进程释放描述符可以引用的文件上的任何一把锁.对于第一条规则的理解应该没有分歧.但对于第二条规则的理解,则会出现疑惑,执行close(fd)的时候,是仅仅释放closf(fd)调用进程在文件上的记录锁,还是会释放所有进程(包括非调用进程)在文件上的记录锁.本文通过具体相关程序对此问题进行验证. 思路:需要设计验证程序对此问题进行验证,通过fork产生

SylixOS文件记录锁使用

1. 文件记录锁介绍 文件锁锁定的是整个文件,而记录锁定还可以锁定文件的某一特定部分,即从文件的某一相对位置开始的一段连续的字节流. 当一个进程正在读取或者修改文件的某个部分时,使用文件记录锁可以阻止其他进程修改同一文件的相同区域.它可以用来锁定文件的某个区域或者整个文件,SylixOS 支持多种文件记录锁 API. 注:SylixOS 支持多种设备驱动模型,但是目前只有 NEW_1 型设备驱动支持文件记录锁功能,此类驱动文件节点类似于UNIX 系统的 vnode. 2. 文件记录锁设置 Syl

记录锁

记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以阻止其它进程修改同一文件区.fcntl函数可以实现这一功能. #include <fcntl.h> int fcntl(int fd, int cmd, ... /* arg */ ); 对于记录锁,cmd是F_GETLK.F_SETLK或F_SETLKW,第三个参数是一个指向flock结构的指针: struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK,

APUE: 文件和目录相关的系统调用

Tips:下面的总结是参考APUE(unix环境高级编程)这本书,在linux(ubuntu)上的实现. Linux系统的调用结构: 最上层:应用程序+shell命令(外部命令在coreutils中实现,内部命令在bash中实现) 中间层:linux下的库函数(gnu的c标准库在glibc中实现) 最底层:linux内核(163个linux系统调用接口+内核子系统(驱动)) 系统调用是linux内核和外部的唯一接口. unix的标准主要有两个: posix标准:可移植操作系统接口,IEEE.IS

Linux环境编程之高级I/O(一):非阻塞I/O、记录锁

引言:高级I/O包括非阻塞I/O.记录锁.系统V流机制.I/O多路转接(select和poll函数).readv和writev函数以及存储映射I/O. (一)非阻塞I/O 可能会使进程永远阻塞的一类系统调用有: 1.如果某些文件类型的数据并不存在,则读操作可能会使调用者永远阻塞. 2.如果数据不能立即被上述同样类型的文件接受,则写操作也会使调用者永远阻塞. 3.在某种条件发生之前,打开某些类型的文件会阻塞. 4.对已经加上强制记录锁的文件进行读.写. 5.某些ioctl操作. 6.某些进程间通信

记录锁(record locking)机制

要讲解记录锁机制,首先要介绍fcntl函数,如下给出该函数原型: #include <fcntl.h> int fcntl(int filedes, int cmd, ... /* struct flock *flockptr */) 函数返回值:若成功则依赖于cmd,若出错则返回-1. 对于记录锁,cmd是F_GETLK, F_SETLOCK, F_SETLKW.第三个参数(称其为flockptr)是一个指向flock结构的指针: struct flock { short l_type; /

APUE学习-记录一

从开始看APUE已经有快一个星期了,由于正好赶上这几天清明节放假,难得有了三天空闲假期可以不受打扰的学习APUE,现在已经看完前六章了,里面的大部分例程也都亲自编写,调试过了.但总觉得这样学过就忘,因此决定把这个学习过程记录下来,学到后面章节的时候回顾前面的章节,做到温故知新.也可以将自己在学习过程中遇到的问题记录下来. 本书对UNIX系统的提供的接口的方方面面进行了讲解,中间还穿插介绍了很多UNIX或类UNIX系统的相关知识,即使现在我只是看过了前六章,也感觉学到了不少知识,解决了我以前对LI

Linux IPC 同步(三):记录锁

进程间的互斥,我们可以让这些进程共享某个内存区(mmap实现),然后在该共享内存区中使用某种类型的同步变量 但是,fcntl记录上锁往往更容易使用. #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ... /* struct flock *arg */ ); struct flock { ... short l_type; /* Type of lock: F_RDLCK, F_WRLCK, F_U

unix 中的记录锁

如果一个文件被两个人同时修改会出现什么结果呢?在很多unix系统中,该文件的最后状态取决于写该文件的最后一个进程.但是对于有些应用程序(例如数据库),进程有时需要确保它正在单独写一个文件.为了向进程提供这种功能,商用unix系统提供了记录锁机制. 记录锁的功能是:当一个进程正在读或修改文件的某个部分时,它可以组织其他进程修改同一文件区.对于unix系统而言,"记录"这个次是一种误会,因为unix系统内核根本没有使用文件记录这种概念.更适合的术语可能是"字节范围锁",