1、什么是文件和记录锁定?
文件锁定的是整个文件,而记录锁定只锁定文件的一部分,文件和记录锁分为咨询式锁定和强制锁定
1)咨询式锁定
某个进程对某个文件进行了咨询式锁定,其他想访问该文件的进程将会被操作系统告知文件已经上锁,但并不阻止这些进程对锁定文件的操作,只要有对锁定文件的存取权,这些进程便可忽略咨询式锁定而去写文件。比如Symtem V和BSD两种锁
2)强制锁定
操作系统会对每一个读写文件的请求进行核查,只有在确认该请求下不会干扰上了锁的文件,才允许对应的操作。
2、System V的咨询锁定
锁函数为lockf()
#include <unistd.h> int lockf(int fd, int function, long size); /* 参数fd 是在文件打开操作中获得的文件描述符; 参数function 可以取如下的参数值: F_ULOCK 为一个先前锁定的区域解锁 F_LOCK 锁定一个区域 F_TLOCK 测试并锁定一个区域 F_TEST 测试一个区域是否已经上锁。 参数size 指明了从文件当前位置开始的一段连续锁定区域的长度,当size 为0 时,锁 定记录将由当前位置一直扩展到文件尾。 */
如果lockf的参数function为F_LOCK指定文件的对应区域已经被其他进程锁定,那么lockf的调用进程将被阻塞直到该区域解锁,这种情况称为阻塞。若参数设定为F_TLOCK,那么当被测试区域上了锁时,lockf将会立即返回-1,这是一个非阻塞调用
下面是上锁和解锁的函数实现
#include <unistd.h> my_lock(int fd) { /* 将文件指针移回文件头 */ lseek(fd,0L,0); /* 锁定整个文件 */ if (lockf(fd,F_LOCK,0L)==-1) { perror("can't F_LOCK"); exit(1); } } my_unlock(int fd) { lseek(fd,0L,0); if(lockf(fd,F_ULOCK,0L)==-1) { perror("can't F_UNLOCK"); exit(1); } }
3、BSD的咨询式锁定
#include <sys/file.h> int flock(int fd, int operation); /* 调用flock 有两个参数: 参数fd 是一个已打开文件的文件描述符; 参数operation 可设定为下述各值: LOCK_SH 共享锁 LOCK_EX 互斥锁 LOCK_UN 解锁 LOCK_NB 当文件已被锁定时不阻塞 */
4、两种锁的比较
1)System V是记录锁定,可以指定锁定的范围,BSD是文件锁定
2)System V是每个进程独有,可以用于父子进程间的共享锁定,而BSD的锁定方式是可以继承的,父子进程间使用的是同一锁定的,所以不能用于父子进程间的文件共享锁。
5、其他锁定技术
创建和使用一个辅助文件以表示进程对共享文件的锁定操作是其他锁技术的基本点,如果辅助文件存在,则资源被其他进程锁定,否则,进程就创建辅助文件以对资源上锁。