注意:锁文件只是充当一个指示器的角色,程序间需要通过相互协作来使用它们,也就是说锁文件只是建议锁,而不是强制锁,并不会真正阻止你读写文件中的数据 。
可以看看下面的例子:源文件文件名为filelock1.c,代码如下:
#include unistd.h #include stdlib.h #include stdio.h #include fcntl.h #include errno.h int main() { const char *lock_file = "/tmp/LCK.test1"; int n_fd = -1; int n_tries = 10; while(n_tries--) { //创建锁文件 n_fd = open(lock_file, O_RDWR|O_CREAT|O_EXCL, 0444); if(n_fd == -1) { //创建失败 printf("%d - Lock already present ", getpid()); sleep(2); } else { //创建成功 printf("%d - I have exclusive access ", getpid()); sleep(1); close(n_fd); //删除锁文件,释放锁 unlink(lock_file); sleep(2); } } return 0; }
同时运行同一个程序的两个实例 , 运行结果为:
?
从运行的结果可以看出两个程序交叉地对对文件进行锁定,但是真实的操作却是,每次调用open函数去检查/tmp/LCK.test1这个文件是否存在,如果存在open调用就失败,显示有进程已经把这个文件锁定了,如果这个文件不存在,就创建这个文件,并显示许可信息 。但是这种做法有一定的缺憾 , 我们可以看到文件/tmp/LCK.test1被创建了很多次 , 也被unlink删除了很多次,也就是说我们不能使用已经事先有数据的文件作为这种锁文件,因为如果文件已经存在 , 则open调用总是失败 。
给我的感觉是,这更像是一种对进程工作的协调性安排 , 更像是二进制信号量的作用,文件存在为0,不存在为1,而不是真正的文件锁定 。
三、区域锁定
我们还有一个问题,就是如果同一个文件有多个进程需要对它进行读写,而一个文件同一时间只能被一个进程进行写操作 , 但是多个进程读写的区域互不相关,如果总是要等一个进程写完其他的进程才能对其进行读写 , 效率又太低,那么是否可以让多个进程同时对文件进行读写以提高数据读写的效率呢?
为了解决上面提到的问题,和出现在第二点中的问题 , 即不能把文件锁定到指定的已存在的数据文件上的问题 , 我们提出了一种新的解决方案,就是区域锁定 。
简单点来说,区域锁定就是,文件中的某个部分被锁定了,但其他程序可以访问这个文件中的其他部分 。
然而,区域锁定的创建和使用都比上面说的文件锁定复杂很多 。
1、创建区域锁定
在Linux上为实现这一功能,我们可以使用fcntl系统调用和lockf调用,但是下面以fcntl系统调用来讲解区域锁定的创建 。
fctnl的函数原理为:
int fctnl(int fildes, int command, ...);
它对一个打开的文件描述进行操作,并能根据command参数的设置完成不同的任务,它有三个可选的任务:F_GETLK , F_SETLK,F_SETLKW,至于这三个参数的意义下面再详述 。而当使用这些命令时,fcntl的第三个参数必须是一个指向flock结构的指针,所以在实际应用中,fctnl的函数原型一般为:int fctnl(int fildes, int command, struct flock *flock_st);
2、flock结构
准确来说,flock结构依赖具体的实现,但是它至少包括下面的成员:
short l_type;文件锁的类型,对应于F_RDLCK(读锁,也叫共享锁),F_UNLCK(解锁,也叫清除锁) , F_WRLCK(写锁,也叫独占锁)中的一个 。
short l_whence;从文件的哪个相对位置开始计算,对应于SEEK_SET(文件头),SEEK_CUR(当前位置),SEEK_END(文件尾)中的一个 。
off_t l_start;从l_whence开始的第l_start个字节开始计算 。
off_t l_len;锁定的区域的长度 。
pid_t l_pid;用来记录参持有锁的进程 。
推荐阅读
- word怎么添加审阅,word怎么增加审阅人
- 包含postgresql认证教程的词条
- python爬虫爬取豆瓣影评,python爬取豆瓣电影并分析
- linux安装桌面命令 linux里面安装gnome桌面
- 全民音乐下载,全民音乐下载歌曲到手机
- phpcmsv9简单应用,phpcms环境搭建
- 网络游戏害人的事例,网络游戏害人的事例有哪些
- java长方形如何敲代码 用java代码画出长方形
- 电脑怎么保养台式机电源,如何保养台式电脑