您的位置:首页 > 运维架构 > Linux

UNIX/LINUX编程学习之文件锁、记录锁

2011-09-14 08:40 239 查看
转自:
http://shihaiyang.iteye.com/blog/482656
锁定中的几个概念

文件锁定的是整个文件,而记录锁定只锁定文件的某一特定部分。UNIX 的记录指的是从文件的某一相对位置开始的一段连续的字节流,它不同于其它以强制性记录结构阻止文件的操作系统,因此,UNIX 记录锁更恰当的称呼应该是范围锁,它是对文件某个范围的锁定。

文件和记录锁定可分为咨询式锁定和强制锁定两种。当正在运行的某一进程对它将要访问的某一文件进行了咨询式锁定后,其它想要访问该文件的进程将被操作系统告知共享文件已经上了锁,但这并不阻止它们对锁定文件的操作。只要有对锁定文件的存取权,这些进程便可忽视咨询式锁定而去写上了锁的文件。强制锁定的含义则要严格多了,当某一共享文件被强制后,操作系统将会对每个读写文件的请求进行核查,只有在确证该请求不会干扰上了锁的文件时,才允许对应的操作。System V和 BSD 都提供了咨询式锁定方式。这两种锁定方式都被Linux
支持。

System V的咨询锁定

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()既可以用来上锁有可以用来测试是否已经赏了锁。 如果 lockf 的参数function为 F_LOCK 指定文件的对应区域已被其它进程锁定,那么 lockf 的调用进程将被阻塞直到该区域解锁。上述情况我们称为阻塞。如果在调用 lockf()时把参数设为 F_TLOVK,那么当被测试的区域上了锁时,lockf 便会立即返回-1,出错返回码 errno 将为 EAGAIN,它是一个非阻塞调用。

C代码



#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);

}

}

BSD的咨询式锁定

BSD UNIX 操作系统提供了如下形式的调用来锁定和解锁一个文件:

#include <sys/file.h>

int flock(int fd, int operation);

调用 flock有两个参数:

参数 fd 是一个已打开文件的文件描述符;

参数 operation 可设定为下述各值:

LOCK_SH 共享锁

LOCK_EX 互斥锁

LOCK_UN 解锁

LOCK_NB 当文件已被锁定时不阻塞

BSD UNIX使用flock()来请求对指定文件的咨询式锁定和解锁。BSD的咨询锁有共享锁和互斥锁两种。在任一给定时刻,多个进程可以用于属于同一文件的共享锁,但是某共享文件不能同时具有多个互斥锁或存在共享锁和互斥锁共存的情况。如果锁定成功,flock将返回零,否则返回-1。

C代码



#include <sys/file.h>

my_flock(int fd)

{

if (flock(fd,LOCK_EX))==-1)

{

perror(“ can LOCK_EX” );

exit(1);

}

}

my_unload(fd)

{

if (flock(fd,LOCK_UN)==-1)

{

perror(“ can’ t LOCK_UN” );

exit(1);

}

}

前面两种锁定方式的比较

由于 Linux 支持上面的两种锁定方式,所以可以根据不同的实际情况选用不同的锁定方式。以上的两种锁定方式有以下的不同:

1.System V的锁定方式是记录锁定,可以指定锁定的范围。而 BSD 的锁定方式是文件锁定,只能指定锁定文件。

2.System V的锁定是每个进程所独有的,可以用于父子进程间的共享锁定。而 BSD的锁定方式是可以继承的,父子进程间使用的是同一锁定的,所以不能用于父子进程间的文件共享锁定
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: