当前位置: 首页 > news >正文

记录上锁

记录上锁 

2012-08-09 21:01:36|  分类: Linux |  标签:linux  |字号订阅

 
 
记录锁可用于有亲缘关系或无亲缘关系的进程之间共享某个 文件的读与写。被锁住的文件通过其描述符访问,执行上锁操作的函数是fcntl。这种类型的锁通常是在内核中维护的,所以这些锁可以用于不同进程间的上锁,而不仅用于同一进程内不同线程间的上锁。
现在假如我们要在不同进程之间进行互斥操作,如果选用互斥锁或者读写锁的话,我们必须先让这些进程共享某个内存区,然后再该共享内存区中使用某种类型的同步变量。而如果使用fcntl记录上锁的话,就不需要共享内存。
下面将着重讲解fcntl函数的使用。
 
POSIX fcntl记录上锁
#include <fcntl.h>
int fcntl(int fd, int cmd, .../*struct flock *arg*/);
用于记录上锁的cmd参数共有三种值。这三个命令要求第三个参数arg是指向某个flock结构的指针
strcut flock {
short  l_type; //F_RDLCK, F_WRLCK, F_UNLCK
short l_whence; //SEEK_SET, SEEK_CUR, SEEK_END
off_t   l_start;
off_t   l_len;
pid_t  l_pid; //PID returned by F_GETLK
}
 
参数cmd的三种命令如下:
  • F_SETLK:获取(l_type成员为F_RDLCK或F_WRLCK)或释放(l_type为F_UNLCK)由arg指向的flock结构所描述的锁。如果无法将该锁授予调用fcntl这个函数的进程,该函数就立即返回一个EACCES或EAGAIN错误而不阻塞。
  • F_SETLCW:该命令与上一个命令类似,不过如果无法将所请求的锁授予调用进程,调用进程将阻塞到该锁能够分配为止。(W的意思就是wait)
  • F_GETLK:检查由arg指向的锁以确定是否有某个已存在的锁会妨碍将新锁授予调用进程。如果当前没有这样的锁存在,那么由arg指向的flock结构的l_type成员就被设置成为F_UNLCK。否则关于这个已存在的锁的信息将在由arg指向的flock结构中返回(也就是说,该结构的内容由fcntl函数覆写),其中包括持有该锁的进程的进程ID。   应该清楚发出F_GETLK命令后紧接着发出F_SETLK命令不是一个原子操作。也就是说,如果我们发出F_GETLK命令,并且执行该命令的fcntl函数返回时设置l_type的值为F_UNLCK,那么跟着立即发出F_SETLK命令不能保证其fcntl函数会成功返回。因为这两次命令调用期间可能有另外一个进程运行并获取了我们想要的锁。   其实提供F_GETLK命令的原因在于:当执行F_SETLK命令的fcntl函数返回一个错误时,导致该错误的某个锁的信息可由F_GETLK命令返回,从而允许我们确定是哪个进程锁住了我们所要请求的文件区。但是即使是这样的情形,F_GETLK命令也可能返回该文件区已解锁的信息,因为在F_SETLK和F_GETLK命令之间,该文件区可能被解锁。
其实flock结构主要是描述锁的类型(读入锁或者是写入锁)以及待锁住的字节范围。跟lseek一样,起始字节偏移是作为一个相对偏移(l_start)伴随其解释(l_whence)制定的。
l_whence成员有三种取值:
  1. SEEK_SET:l_start相对于文件的开头解释。
  2. SEEK_CUR:l_start相对于文件的当前字节偏移。即当前读写指针的位置。
  3. SEEK_END:l_start相对于文件的末尾解释。
l_len成员指定从该偏移位置开始的连续字节数。l_len为0的时候意味着“从起始偏移位置到文件偏移的最大可能值”。
 
PS:对于一个打开着某个文件的进程来说,当它关闭该文件或者它本身终止时,与该文件关联的所有锁都被删除。这里说的锁仅限于用fcntl记录上的锁。而如果是互斥锁,条件变量,读写锁,POSIX信号量的话,并不在进程结束的时候执行清理工作。

转载于:https://www.cnblogs.com/siguoya/p/3512051.html

相关文章:

  • Markdown学习笔记
  • 《需求工程》阅读随笔-1.做什么和怎么做
  • curl_errno错误码说明
  • 《Genesis-3D开源游戏引擎完整实例教程-2D射击游戏篇03:子弹发射》
  • 交换机的link-dependency链路依赖功能
  • 打开FTP服务器上的文件夹时发生错误,请检查是否有权限访问该文件夹
  • 解决:导入第三方jar包后,仍然出现java.lang.NoClassDefFoundError的错误
  • javascript deferred
  • c#对象的内存结构(学习笔记)
  • 学习python的网址
  • 45 个非常有用的 Oracle 查询语句
  • Oracle 创建表空间一边串过程
  • 解读《TCP/IP详解》(卷1):03章:IP(网际协议)
  • LeetCode: Reverse Linked List II
  • oracle临时表(JDBC应用)
  • - C#编程大幅提高OUTLOOK的邮件搜索能力!
  • Java知识点总结(JavaIO-打印流)
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • vue2.0项目引入element-ui
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 聊聊sentinel的DegradeSlot
  • 前端性能优化--懒加载和预加载
  • 人脸识别最新开发经验demo
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 移动端唤起键盘时取消position:fixed定位
  • ​iOS安全加固方法及实现
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #android不同版本废弃api,新api。
  • #NOIP 2014# day.2 T2 寻找道路
  • #QT(串口助手-界面)
  • #微信小程序(布局、渲染层基础知识)
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (十一)手动添加用户和文件的特殊权限
  • (四) Graphivz 颜色选择
  • (算法)前K大的和
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)VC++中ondraw在什么时候调用的
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .NET4.0并行计算技术基础(1)
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • @RunWith注解作用
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项
  • [BZOJ1053][HAOI2007]反素数ant
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
  • [ERROR] 不再支持目标选项 5。请使用 7 或更高版本
  • [iOS]-网络请求总结
  • [LeetCode] 19. 删除链表的倒数第 N 个结点
  • [LeetCode] Wildcard Matching
  • [leetcode]Search a 2D Matrix @ Python