近日小温下APUE,发现Linux下的 fcntl 实现强制锁的功能好像都没试验过,简单做个测试。

首先用 fcntl 实现建议锁(Advisory locking),比较简单,贴个最简单的代码:

#include

#include

#include

#include

#include

#include

int main(int argc, char ** argv)

{

int fd = 0, ret = 0;

struct flock lock = {0};

lock.l_type = F_WRLCK;

lock.l_whence = SEEK_SET;

lock.l_start = 0;

lock.l_len = 0;

fd = open("test.file", O_RDWR | O_CREAT);

printf("before flock\n");

ret = fcntl(fd, F_SETLKW, &lock);

printf("after flock, ret: %d\n", ret);

getchar();

close(fd);

return 0;

}

关键的几句已高亮显示,用 F_SETLKW 等待写的锁,很好测试,分别开一个终端运行一次就可以测试出来。

Linux 同时实现了 POSIX 的 fcntl 锁函数,BSD 的 flock 函数,SVR4 的 lockf 函数,这些默认都是建议锁。

这个简单的实现只是建议锁,需要每个对文件的操作的进程都遵循同样的锁操作才能起作用,这些进程称为合作进程(Cooperative processes),但实际使用时会有例外的情况,如果另外开一个终端窗口直接写 test.file 文件,会发现可以直接写,因为这种写没有锁操作,不是合作进程,这种情况就需要用强制锁(Mandatory locking)了。

强制锁的实际代码和上面的完全一样,不过在 Linux 上需要做一些改动:

挂载文件系统时需要加 mand 参数在文件系统上启用强制锁支持,比较新的 Linux kernel 里已经基本在所有文件系统上都实现了;

去掉程序的组执行权限;

增加程序的设置组ID权限。

第二项和第三项在普通情况下实际上是自相矛盾的,所以 Linux 就用这种特殊情况就表示启用强制锁(Mandatory locking)了。

备注

使用 BSD 的 flock 函数时不能使用强制锁,见 Linux kernel 源码下 mandatory-locking.txt 中的说明:

Mandatory locks can only be applied via the fcntl()/lockf() locking

interface - in other words the System V/POSIX interface. BSD style

locks using flock() never result in a mandatory lock.

如果一个文件被某进程强制锁住,另一个进程通过 creat 函数或者 open 时加 O_TRUNC 参数,都会导致函数调用失败;

强制锁在不同的 UNIX 及 类UNIX 系统中实现不同,第二个备注中的 O_TRUNC 参数便是 Linux kernel 和 HP-UX 不同的地方;

tmpfs、nfs 也支持强制锁,可以用这两个文件系统方便测试;

删除文件(unlink操作)再重新创建文件,会导致强制锁失效;

Linux kernel 的强制锁的实现并不完全可靠(感觉白写了,哈哈,实际情况还要做处理),见 man fcntl 的说明。

强制锁的实际操作:

mount -t tmpfs -o size=10m,mand tmpfs /mnt

cp test /mnt

cd /mnt

chmod g-x test

chmod g+s test

运行 test 程序,同时开另一个终端,直接用 echo 读写 test 文件,会发现强制锁已经起作用。

无相关文章.

linux中断函数中有锁,Linux下fcntl实现建议锁和强制锁相关推荐

  1. linux free函数头文件,Linux_Linux下malloc/free与new/delete的区别,由于malloc/free是库函数,不是 - phpStudy...

    Linux下malloc/free与new/delete的区别 由于malloc/free是库函数,不是运算符,他们不能执行构造函数和析构函数,只是负责分配内存. 1.malloc与free是C++/ ...

  2. linux 中断 c语言程序,linux驱动之中断处理过程C程序部分

    当发生中断之后,linux系统在汇编阶段经过一系列跳转,最终跳转到asm_do_IRQ()函数,开始C程序阶段的处理.在汇编阶段,程序已经计算出发生中断的中断号irq,这个关键参数最终传递给asm_d ...

  3. linux 变量函数返回值,linux shell 自定义函数(定义、返回值、变量作用域)介绍...

    linux shell 可以用户定义函数,然后在shell脚本中可以随便调用.下面说说它的定义方法,以及调用需要注意那些事项. 一.定义shell函数(define function) 语法: [ f ...

  4. linux abs函数怎么用,Linux输入子系统详解

    原标题:Linux输入子系统详解 纯手工打造每一篇开源资讯与技术干货,数十万程序员和Linuxer已经关注. 导读 linux输入子系统由驱动层.输入子系统核心.事件处理层三部分组成.一个输入事件,如 ...

  5. linux 中断和进程 传递,Linux内核之进程上下文和中断上下文的区别

    进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不断被提及,是最经常接触.看上去很懂但又说不清楚到底怎么回事.造成这种局面的原因,可能是原来接触到的操作系统课程的教学总停 ...

  6. Linux绘图函数与驱动,Linux中与驱动相关的ioctl函数

    一:    ioctl函数的作用 ioctl用于向设备发控制和配置命令 ,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据.也就是说,read/ ...

  7. linux read函数段错误,linux C++ 莫名奇异的段错误(segmentation fault),无法调用其他函数...

    进来在linux下开发C++项目,遇到了非常奇怪的bug. 项目须要多线程实现,在写好代码后,每当执行到线程函数内部,当内部调用其他函数如printf.fopen等时就会提示段错误(segmentat ...

  8. linux用函数输出进程信息,Linux进程的管理 获取进程信息函数

    进程又称任务,是一个动态的使用系统资源.处于活动状态的应用程序. 进程的管理由进程控制块PCB.进程调度.中断管理.任务队列等组成,它是linux文件系统.存储管理.设备管理和驱动程序的基础. 进程控 ...

  9. linux touch 函数,C实现Linux之touch命令

    Linux 的 touch 命令用来修改文件时间戳,或者新建一个不存在的文件,使用方式如下: touch [-acm][-r ref_file(参照文件)|-t time(时间值)] file(文件名 ...

最新文章

  1. ZOJ 38727(贪心)
  2. java spring入门小程序_springMVC学习笔记(二)-----注解和非注解入门小程序
  3. python怎么打开文件解释_python怎么打开文件的路径?
  4. 闪寸 U盘 检测工具 量产工具
  5. html div 怎么排版,请html大神解决一个div排版的问题
  6. 揭秘跨境电商亚马逊店铺最新骗局!!小白做亚马逊店铺如何防止上当受骗?
  7. Codeforces - 1102F - Elongated Matrix(建图 + 哈密顿通路)
  8. 依赖性检查工具Snyk与Dependency-check对比
  9. 禁用win10系统的Cortana小娜进程,笔记本散热风扇冷静了
  10. 开源项目—FLutter/iOS/Android编写的三个计算器APP
  11. Python提取PPT中的图片
  12. redis设置expire以及删除机制
  13. C语言排列组合(函数
  14. python add argument list_python argh/argparse:我如何传递一个列表作为命令行参数?
  15. C++语言程序设计课程设计任务书
  16. 【第一个项目开发】创建domain包中的类
  17. 突然不能从主机向虚拟机上拷贝文件了
  18. RFID复习笔记(4)——RFID的射频前端
  19. Magic Leap开发指南(5)-- Hand Tracking
  20. python使用中文-Python中使用中文

热门文章

  1. c mysql insert语句_MySQL_mysql insert详细讲解,INSERT语法 INSERT [LOW_PRIORITY |DELA - phpStudy...
  2. 1.13 梯度检验-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授
  3. android4.0 系统广播集
  4. C++派生类构造函数调用规则
  5. 三阶魔方花样玩法,公式汇总
  6. VII Python(9)socket编程
  7. Keepalived的相关应用,使用keepalived实现nginx和lvs的高可用负载均衡器
  8. Logical Volume Manager(逻辑卷管理)
  9. 科研经验:一篇学术文章要写多久
  10. DW的代码格式化和净化功能