文件锁fcntl()函数的使用

问:为什么要使用文件锁?

答:当多个用户共同使用、操作一个文件的情况时,Linux采用的方法就是给文件上锁,来避免共享的资源产生竞争的状态。

问:文件锁有哪些类型?

答:文件锁包括建议性锁和强制性锁。一般情况下,内核和系统都不适用建议性锁,采用强制性锁的影响很大,每次读写操作都必须检查是否有所存在。

问:怎样实现文件上锁?

答:在Linux中,实现文件上锁的函数有lockf() 和fcntl() ,其中lockf()用于对文件施加建议性锁,而fcntl() 不仅可以施加建议性锁,而且可以施加强制性锁。fcntl()还能对文件的某一记录上锁,也就是记录锁。记录锁又可分读取锁(共享锁)和写入锁(排斥锁),文件的同一部分不能同时建立读取锁和写入锁。

fcntl()使用实例:

文件记录锁功能源代码:

[cpp] view plain copy
  1. /* 
  2.  * lock_set.c 
  3.  * 
  4.  *  Created on: 2012-7-17 
  5.  *      Author: liwei.cai 
  6.  */  
  7. int lock_set(int fd, int type)  
  8. {  
  9.     struct flock old_lock, lock;  
  10.     lock.l_whence = SEEK_SET;  
  11.     lock.l_start = 0;  
  12.     lock.l_len = 0;  
  13.     lock.l_type = type;  
  14.     lock.l_pid -1;  
  15.   
  16.     //判断文件是否上锁  
  17.     fcntl(fd, F_GETLK, &lock);  
  18.     if (lock.l_type != F_UNLCK)  
  19.     {  
  20.         //判断文件不能上锁的原因  
  21.         if (lock.l_type == F_RDLCK) //该文件已有读取锁  
  22.         {  
  23.             printf("Read lock already set by %d .\n", lock.l_pid);  
  24.         }  
  25.         else if(lock.l_type == F_WRLCK) //该文件已有写入锁  
  26.         {  
  27.             printf("Write lock already set by %d .\n", lock.l_pid);  
  28.         }  
  29.     }  
  30.     //l_type 可能已被F_FETLK修改过  
  31.     lock.l_type = type;  
  32.   
  33.     //根据不同的type值进行阻塞式上锁或解锁  
  34.     if((fcntl(fd, F_SETLKW, &lock)) < 0)  
  35.     {  
  36.         printf("Lock failed:type = %d\n", lock.l_type);  
  37.         return 1;  
  38.     }  
  39.   
  40.     switch(lock.l_type)  
  41.     {  
  42.     case F_RDLCK:  
  43.         {  
  44.             printf("Read lock set by %d \n", getpid());  
  45.         }  
  46.         break;  
  47.     case F_WRLCK:  
  48.         {  
  49.             printf("Write lock set by %d \n", getpid());  
  50.         }  
  51.         break;  
  52.     case F_UNLCK:  
  53.         {  
  54.             printf("Release lock by %d \n", getpid());  
  55.             return 1;  
  56.         }  
  57.         break;  
  58.     default:  
  59.         break;  
  60.     }  
  61.     return 0;  
  62. }  

文件写入锁的测试用例,这里首先创建了一个“hello”文件,之后对其上写入锁,最后释放写入锁。

[cpp] view plain copy
  1. /* 
  2.  * write_lock.c 
  3.  * 
  4.  *  Created on: 2012-7-17 
  5.  *      Author: liwei.cai 
  6.  */  
  7. #include <unistd.h>  
  8. #include <sys/file.h>  
  9. #include <sys/types.h>  
  10. #include <sys/stat.h>  
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13. #include "lock_set.c"  
  14.   
  15. int main()  
  16. {  
  17.     int fd;  
  18.   
  19.     //首先打开文件  
  20.     fd = open("hello", O_RDWR|O_CREAT, 0644);  
  21.     if (fd < 0)  
  22.     {  
  23.         printf("Open file error!\n");  
  24.         exit(1);  
  25.     }  
  26.     //给文件上写入锁  
  27.     lock_set(fd, F_WRLCK);  
  28.     getchar();  
  29.     //给文件解锁  
  30.     lock_set(fd, F_UNLCK);  
  31.     getchar();  
  32.     close(fd);  
  33.     exit(0);  
  34. }  
建议开启两个终端,并且同时运行该程序,以达到多个进程操作一个文件的效果,并查看结果。

读取锁与写入锁类似。

[cpp] view plain copy
  1. /* 
  2.  * fcntl_read.c 
  3.  * 
  4.  *  Created on: 2012-7-17 
  5.  *      Author: liwei.cai 
  6.  */  
  7. #include <unistd.h>  
  8. #include <sys/file.h>  
  9. #include <sys/types.h>  
  10. #include <sys/stat.h>  
  11. #include <stdio.h>  
  12. #include <stdlib.h>  
  13. #include "lock_set.c"  
  14.   
  15. int main()  
  16. {  
  17.     int fd;  
  18.   
  19.     //首先打开文件  
  20.     fd = open("hello", O_RDWR|O_CREAT, 0644);  
  21.     if (fd < 0)  
  22.     {  
  23.         printf("Open file error!\n");  
  24.         exit(1);  
  25.     }  
  26.     //给文件上写入锁  
  27.     lock_set(fd, F_RDLCK);  
  28.     getchar();  
  29.     //给文件解锁  
  30.     lock_set(fd, F_UNLCK);  
  31.     getchar();  
  32.     close(fd);  
  33.     exit(0);  
  34. }  
从结果中可以很好的看出共享锁与排斥锁的区别。

你可能感兴趣的:(文件锁fcntl()函数的使用)