UNIX网络编程卷2进程间通信读书笔记----记录锁

本文详细介绍了记录锁的功能、分类、加锁规则及应用场景等内容,并探讨了记录锁与进程间的关系、死锁问题及其在NFS上的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(笔记从chinaunix copy过来的,然后自己看书的时候把认为需要注意的地方添加上,方便复习) 

1记录锁的功能

       当一个进程正在读或修改文件的某个部分时,它可以阻止其他进程修改同一文件区。我们不应该从字面上去理解记录锁,实际上它应该叫区域锁,因为它锁定的只是文件的一部分(也可能是整个文件)(实现了多进程可以同时写文件的不同部分)。这个区域用来存放多用户的共享区。

注意:记录锁在内核中维护,其属主是由属主的进程ID进行标识的,意味着这些锁用于不同进程间的上锁,而不是用于同一进程内不同线程间的上锁。。

2.记录锁的分类

       记录锁分为共享读锁和独占写锁,前者也叫做共享锁后者也叫做排他锁。

         Posix记录上锁称为劝告性上锁(为什么劝告性锁对协作进程来说就够用了???),其含义是内核维护着已由各个进程上锁的所有文件的信息,但是它不能防止一个进程写已由另一个进程读锁定的某个文件,同样,也不能防止一个进程读已由另一个进程写锁定的某个文件(前提进程有足够读写权限),同步安全性更依赖于程序员控制(即假定程序员会遵守某些规则)


劝告性上锁和强制性上锁区别就象红绿灯,红灯表示有锁,但是不能阻止人们(进程)闯红灯(获得锁),此处红灯只有劝告性作用,强制性就象在马路两边加上护栏or协管(作用等同于内核),不让你闯!这就是强制性)

3.加锁规则

      如果一个进程对共享区加了共享读锁,其他进程只能加共享读锁。如果一个进程加了独占写锁,其他进程就不能加任何锁。


注意:当前读锁,那么一个等待着的写入者与等待着的读出者优先级比较一般系统都采用FIFO规则处理,也就有可能一直来读,写入者处于一直等待。不过估计会采用一些规则判断等待时间,等待时间长了就会运行


4.死锁

       如果两个相互等待对方持有并且不释放(已被锁定)的资源是时,则这两个进程就处于死锁状态。如果一个进程已经控制了文件的一个加锁区域,然后它又试图对另一个进程控制的区域加锁,则它就会睡眠,在这种情况下,有发生死锁的可能性

5.锁的隐含继承和释放

1)锁与进程和文件两方面有关系,它和前者关系是:当一个进程结束后,他对文件加的锁也就消失了。它和后者的关系是:当进程close文件描述符,切断文件和进程的联系进程所创建的锁也会消失。

2fork产生的子进程不继承父进程所设置的锁。这意味着,若一个进程得到一把锁,然后调用fork,那么对于父进程创建的锁而言,子进程被视为另一个进程,不会拥有该锁。

3在执行exec后,新进程可以继承原执行的锁。因为执行exec前后还是一个进程。我们只是改变进程执行的程序,并没有创建新的进程

6启动一个守护进程的唯一副本  记录上锁的一个常见用途是确保某个程序(例如守护进程)在任何时刻只有一个副本在运行。其实就是一个文件的写入锁。运行程序时获取一个文件的写入锁,此处可以是一个文件中一个区域,然后当再次运行该程序时,无法获取该区域的写入锁,保证了唯一副本。

7NFS上锁

       NFS网络文件系统,NFS的大多数实现支持fcntl记录上锁。其实就是当检测到文件描述符指向NFS文件系统时,本地lockd就向服务器的lockd发送锁请求。

8.要注意的问题

    1记录锁只是提供竞争进入某段代码区的功能,不会导致对文件操作失败。也就是说,我们对文件进行加锁后,我们还是可以对文件进行操作。


名称 : :

fcntl

功能 :

对文加解锁。

头文件 :

#include <pthread.h>

函数原形 :

int fcntl(int filedes,int cmd,…/*struct flock *flockptr */) ;

参数 :

filedes   文件描述符

cmd     测试锁或加锁

flockptr  指向 flock 结构的指针

返回值:

若成功返回 0 ,若失败返回错误编号。

      

 

 

 

 

 

 

  对于记录锁, cmd 是 F_GETLK,F_SETLKW 或 F_SETLKW. 。

       F_GETLK 判断由 flockptr 所描述的锁是否会被另外一把锁排斥。如果存在一把锁,他阻止创建由 flockptr 所描述的锁,则把该现存锁的信息写到 flockptr 指向的结构中。如果不存在这种情况除了将 l_type 设置为 F_UNLCK 之外, flockptr 所描述的其他信息都不变。

F_SETLK 和 F_SETLKW 企图建立一把锁。 F_SETLK 和 F_SETLKW 的区别是 F_SETLKW 是 F_SETLK 的阻塞版本。如果存在其他锁,调用的进程就被阻塞直道捕捉到信号。

       第三个参数是一个指向 flock 结构的指针:

struct flock{

       short l_type; /*F_RDLCK,F_WRLCK,F_UNLCK*/

       off_t l_start; /* 加锁的地址 */

       shout l_whence; /* 加锁的偏移地址 */

       off_t l_len; /* 加锁区域的长度 */

       pid_t l_pid; /* 持有锁的进程 ID*/

};

flock 结构说明:

所希望的锁类型: F_RDLCK( 共享读锁 ) 、 F_WRLCK( 独占性写锁 ) 、 F_UNLCK( 解锁一个区域 ) ,这是由 l_type决定的。

要加锁或解锁区域的起始字节偏移量,这是由 l_statt 和 l_whence 两者决定。

区域的字节长度,由 l_len 表示。

具有能阻塞当前进程的锁,其持有的 ID 存放在 l_pid 中。

       如若 l_len 为 0 ,则表示锁的区域从其起点(由 l_start 和 l_whence 决定)开始直至最大可能位置为止。也就是不管添写到该文件中多少数据,它都处于的范围。

       如果想锁住整个文件,通常的方法是将 l_start 说明为 0 , l_whence 说明为 SEEK_SET , 1_len 说明为 0 。

       还要注意的是,对文件加共享读锁时文件应以只读的方式打开,对文件加独占写锁时文件应以只读的方式打开。


名称 

fcntl

功能 

对文加解锁。

头文件 

#include <pthread.h>

函数原形 

int fcntl(int filedes,int cmd,…/*struct flock *flockptr */) 

参数 

filedes   文件描述符

cmd     测试锁或加锁

flockptr  指向 flock 结构的指针

返回值:

若成功返回 ,若失败返回错误编号。

      

 

 

 

 

 

 

 

 

 

 

 

 

  对于记录锁, cmd  F_GETLK,F_SETLKW  F_SETLKW. 

       F_GETLK 判断由 flockptr 所描述的锁是否会被另外一把锁排斥。如果存在一把锁,他阻止创建由 flockptr 所描述的锁,则把该现存锁的信息写到 flockptr 指向的结构中。如果不存在这种情况除了将 l_type 设置为 F_UNLCK 之外, flockptr 所描述的其他信息都不变。

F_SETLK  F_SETLKW 企图建立一把锁。 F_SETLK  F_SETLKW 的区别是 F_SETLKW  F_SETLK 的阻塞版本。如果存在其他锁,调用的进程就被阻塞直道捕捉到信号。

       第三个参数是一个指向 flock 结构的指针:

struct flock{

       short l_type; /*F_RDLCK,F_WRLCK,F_UNLCK*/

       off_t l_start; /* 加锁的地址 */

       shout l_whence; /* 加锁的偏移地址 */

       off_t l_len; /* 加锁区域的长度 */

       pid_t l_pid; /* 持有锁的进程 ID*/

};

flock 结构说明:

所希望的锁类型: F_RDLCK( 共享读锁  F_WRLCK( 独占性写锁  F_UNLCK( 解锁一个区域 ,这是由 l_type决定的。

要加锁或解锁区域的起始字节偏移量,这是由 l_statt  l_whence 两者决定。

区域的字节长度,由 l_len 表示。

具有能阻塞当前进程的锁,其持有的 ID 存放在 l_pid 中。

       如若 l_len  ,则表示锁的区域从其起点(由 l_start  l_whence 决定)开始直至最大可能位置为止。也就是不管添写到该文件中多少数据,它都处于的范围。

       如果想锁住整个文件,通常的方法是将 l_start 说明为  l_whence 说明为 SEEK_SET  1_len 说明为 

       还要注意的是,对文件加共享读锁时文件应以只读的方式打开,对文件加独占写锁时文件应以只读的方式打开。

第一部分 简介   第1章 简介 2   1.1 概述 2   1.2 进程、线程与信息共享 3   1.3 IPC对象的持续性 4   1.4 名字空间 5   1.5 fork、exec和exit对IPC对象的影响 7   1.6 出错处理:包裹函数 8   1.7 Unix标准 9   1.8 书中IPC例子索引表 11   1.9 小结 13   习题 13   第2章 Posix IPC 14   2.1 概述 14   2.2 IPC名字 14   2.3 创建与打开IPC通道 16   2.4 IPC权限 18   2.5 小结 19   习题 19   第3章 System V IPC 20   .3.1 概述 20   3.2 key_t键和ftok函数 20   3.3 ipc_perm结构 22   3.4 创建与打开IPC通道 22   3.5 IPC权限 24   3.6 标识符重用 25   3.7 ipcs和ipcrm程序 27   3.8 内核限制 27   3.9 小结 28   习题 29   第二部分 消息传递   第4章 管道和FIFO 32   4.1 概述 32   4.2 一个简单的客户-服务器例子 32   4.3 管道 32   4.4 全双工管道 37   4.5 popen和pclose函数 39   4.6 FIFO 40   4.7 管道和FIFO的额外属性 44   4.8 单个服务器,多个客户 46   4.9 对比迭代服务器与并发服务器 50   4.10 字节流与消息 51   4.11 管道和FIFO限制 55   4.12 小结 56   习题 57   第5章 Posix消息队列 58   5.1 概述 58   5.2 mq_open、mq_close和mq_unlink函数 59   5.3 mq_getattr和mq_setattr函数 61   5.4 mq_send和mq_receive函数 64   5.5 消息队列限制 67   5.6 mq_notify函数 68   5.7 Posix实时信号 78   5.8 使用内存映射I/O实现Posix消息队列 85   5.9 小结 101   习题 101   第6章 System V消息队列 103   6.1 概述 103   6.2 msgget函数 104   6.3 msgsnd函数 104   6.4 msgrcv函数 105   6.5 msgctl函数 106   6.6 简单的程序 107   6.7 客户-服务器例子 112   6.8 复用消息 113   6.9 消息队列上使用select和poll 121   6.10 消息队列限制 122   6.11 小结 124   习题 124   第三部分 同步   第7章 互斥锁和条件变量 126   7.1 概述 126   7.2 互斥锁:上锁与解锁 126   7.3 生产者-消费者问题 127   7.4 对比上锁与等待 131   7.5 条件变量:等待与信号发送 132   7.6 条件变量:定时等待和广播 136   7.7 互斥锁和条件变量的属性 136   7.8 小结 139   习题 139   第8章 读写锁 140   8.1 概述 140   8.2 获取与释放读写锁 140   8.3 读写锁属性 141   8.4 使用互斥锁和条件变量实现读写锁 142   8.5 线程取消 148   8.6 小结 153   习题 153   第9章 记录上锁 154   9.1 概述 154   9.2 对比记录上锁与文件上锁 157   9.3 Posix fcntl记录上锁 158   9.4 劝告性上锁 162   9.5 强制性上锁 164   9.6 读出者和写入者的优先级 166   9.7 启动一个守护进程的唯一副本 170   9.8 文件作锁用 171   9.9 NFS上锁 173   9.10 小结 173   习题 174   第10章 Posix信号量 175   10.1 概述 175   10.2 sem_open、sem_close和sem_   unlink函数 179   10.3 sem_wait和sem_trywait函数 180   10.4 sem_post和sem_getvalue函数 180   10.5 简单的程序 181   10.6 生产者-消费者问题 186   10.7 文件上锁 190   10.8 sem_init和sem_destroy函数 191   10.9 多个生产者,单个消费者 193   10.10 多个生产者,多个消费者 19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值