问:为什么要使用文件锁?
答:当多个用户共同使用、操作一个文件的情况时,Linux采用的方法就是给文件上锁,来避免共享的资源产生竞争的状态。
问:文件锁有哪些类型?
答:文件锁包括建议性锁和强制性锁。一般情况下,内核和系统都不适用建议性锁,采用强制性锁的影响很大,每次读写操作都必须检查是否有所存在。
问:怎样实现文件上锁?
答:在Linux中,实现文件上锁的函数有lockf() 和fcntl() ,其中lockf()用于对文件施加建议性锁,而fcntl() 不仅可以施加建议性锁,而且可以施加强制性锁。fcntl()还能对文件的某一记录上锁,也就是记录锁。记录锁又可分读取锁(共享锁)和写入锁(排斥锁),文件的同一部分不能同时建立读取锁和写入锁。
fcntl()使用实例:
文件记录锁功能源代码:
/* * lock_set.c * * Created on: 2012-7-17 * Author: liwei.cai */ int lock_set(int fd, int type) { struct flock old_lock, lock; lock.l_whence = SEEK_SET; lock.l_start = 0; lock.l_len = 0; lock.l_type = type; lock.l_pid -1; //判断文件是否上锁 fcntl(fd, F_GETLK, &lock); if (lock.l_type != F_UNLCK) { //判断文件不能上锁的原因 if (lock.l_type == F_RDLCK) //该文件已有读取锁 { printf("Read lock already set by %d .\n", lock.l_pid); } else if(lock.l_type == F_WRLCK) //该文件已有写入锁 { printf("Write lock already set by %d .\n", lock.l_pid); } } //l_type 可能已被F_FETLK修改过 lock.l_type = type; //根据不同的type值进行阻塞式上锁或解锁 if((fcntl(fd, F_SETLKW, &lock)) < 0) { printf("Lock failed:type = %d\n", lock.l_type); return 1; } switch(lock.l_type) { case F_RDLCK: { printf("Read lock set by %d \n", getpid()); } break; case F_WRLCK: { printf("Write lock set by %d \n", getpid()); } break; case F_UNLCK: { printf("Release lock by %d \n", getpid()); return 1; } break; default: break; } return 0; }
/* * write_lock.c * * Created on: 2012-7-17 * Author: liwei.cai */ #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include "lock_set.c" int main() { int fd; //首先打开文件 fd = open("hello", O_RDWR|O_CREAT, 0644); if (fd < 0) { printf("Open file error!\n"); exit(1); } //给文件上写入锁 lock_set(fd, F_WRLCK); getchar(); //给文件解锁 lock_set(fd, F_UNLCK); getchar(); close(fd); exit(0); }建议开启两个终端,并且同时运行该程序,以达到多个进程操作一个文件的效果,并查看结果。
读取锁与写入锁类似。
/* * fcntl_read.c * * Created on: 2012-7-17 * Author: liwei.cai */ #include <unistd.h> #include <sys/file.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include "lock_set.c" int main() { int fd; //首先打开文件 fd = open("hello", O_RDWR|O_CREAT, 0644); if (fd < 0) { printf("Open file error!\n"); exit(1); } //给文件上写入锁 lock_set(fd, F_RDLCK); getchar(); //给文件解锁 lock_set(fd, F_UNLCK); getchar(); close(fd); exit(0); }从结果中可以很好的看出共享锁与排斥锁的区别。