码迷,mamicode.com
首页 > 系统相关 > 详细

unix/linux 进程间文件锁

时间:2015-06-23 10:05:11      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

转自 http://www.cnblogs.com/hjslovewcl/archive/2011/03/14/2314333.html

有三种不同的文件锁,这三种都是“咨询性”的,也就是说它们依靠程序之间的
合作,所以一个项目中的所有程序封锁政策的一致是非常重要的,当你的程序需
要和第三方软件共享文件时应该格外地小心。

有 些程序利用诸如 FIlENAME.lock 的文件锁文件,然后简单地测试此类文件是否存在。这种方法显然不太好,因为当产生文件的进程被杀后,锁文件依然存在,这样文件也许会被永久锁住。UUCP 中把产生文件的进程号PID存入文件,但这样做仍然不保险,因为PID的利用是回收型的。

这里是三个文件锁函数:
     flock();
     lockf();
     fcntl();

flock()是从BSD中衍生出来的,但目前在大多数UNIX系统上都能找到,在单个主
机上flock()简单有效,但它不能在NFS上工作。Perl中也有一个有点让人迷惑的
flock()函数,但却是在perl内部实现的。

fcntl()是唯一的符合POSIX标准的文件锁实现,所以也是唯一可移植的。它也同
时是最强大的文件锁--也是最难用的。在NFS文件系统上,fcntl()请求会被递
交给叫rpc.lockd的守护进程,然后由它负责和主机端的lockd对话,和flock()
不同,fcntl()可以实现记录层上的封锁。

lockf()只是一个简化了的fcntl()文件锁接口。

无论你使用哪一种文件锁,请一定记住在锁生效之前用sync来更新你所有的文件
输入/输出。

  1.       lock(fd);  
  2.       write_to(some_function_of(fd));  
  3.       flush_output_to(fd); /* 在去锁之前一定要冲洗输出 */  
  4.       unlock(fd);  
  5.       do_something_else;   /* 也许另外一个进程会更新它 */  
  6.       lock(fd);  
  7.       seek(fd, somewhere); /* 因为原来的文件指针已不安全 */  
  8.       do_something_with(fd); ...  
  9. 一些有用的fcntl()封锁方法(为了简洁略去错误处理):  
  10.      #include <fcntl.h>;  
  11.      #include <unistd.h>;  
  12.      
  13.      read_lock(int fd)   /* 整个文件上的一个共享的文件锁 */  
  14.      {  
  15.          fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET));  
  16.      }  
  17.      
  18.      write_lock(int fd)  /* 整个文件上的一个排外文件锁 */  
  19.      {  
  20.          fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));  
  21.      }  
  22.      
  23.      append_lock(int fd) /* 一个封锁文件结尾的锁, 
  24.                             其他进程可以访问现有内容 */  
  25.      {  
  26.          fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_END));  
  27.      }  
  28. 前面所用的file_lock函数如下:  
  29.      struct flock* file_lock(short type, short whence)  
  30.      {  
  31.          static struct flock ret ;  
  32.          ret.l_type = type ;  
  33.          ret.l_start = 0 ;  
  34.          ret.l_whence = whence ;  
  35.          ret.l_len = 0 ;  
  36.          ret.l_pid = getpid() ;  
  37.          return &ret ;  
  38.      }  
  1. //lock.c  
  2. #include <stdio.h>  
  3. #include <unistd.h>  
  4. #include <fcntl.h>  
  5. #include <string.h>  
  6. struct flock* file_lock(short type, short whence)  
  7. {  
  8.     static struct flock ret;  
  9.     ret.l_type = type ;  
  10.     ret.l_start = 0;  
  11.     ret.l_whence = whence;  
  12.     ret.l_len = 0;  
  13.     ret.l_pid = getpid();  
  14.     return &ret;  
  15. }  
  16. int main()  
  17. {  
  18.     int fd = open("1.txt", O_WRONLY|O_APPEND);  
  19.     for(int i=0; i<1000; ++i) {  
  20.         fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));  
  21.         char buf[1024] = {0};  
  22.         sprintf(buf, "hello world %d/n", i);  
  23.         int len = strlen(buf);  
  24.         write(fd, buf, len);  
  25.         fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));  
  26.         sleep(1);  
  27.     }  
  28.     close(fd);  
  29. }  
  30. //lock2.c...同lock.c相比只是修改了下buf内容  
  31. #include <stdio.h>  
  32. #include <unistd.h>  
  33. #include <fcntl.h>  
  34. #include <string.h>  
  35. struct flock* file_lock(short type, short whence)  
  36. {  
  37.     static struct flock ret;  
  38.     ret.l_type = type ;  
  39.     ret.l_start = 0;  
  40.     ret.l_whence = whence;  
  41.     ret.l_len = 0;  
  42.     ret.l_pid = getpid();  
  43.     return &ret;  
  44. }  
  45. int main()  
  46. {  
  47.     int fd = open("1.txt", O_WRONLY|O_APPEND);  
  48.     for(int i=0; i<1000; ++i) {  
  49.         fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));  
  50.         char buf[1024] = {0};  
  51.         sprintf(buf, "china %d/n", i);  
  52.         int len = strlen(buf);  
  53.         write(fd, buf, len);  
  54.         fcntl(fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));  
  55.         sleep(1);  
  56.     }  
  57.     close(fd);  
  58. }  
  59.    
  60. g++ lock.c -o 1  
  61. g++ lock2.c -o 2  
  62. 执行两个程序就能看到互斥的效果了  

unix/linux 进程间文件锁

标签:

原文地址:http://www.cnblogs.com/QingCHOW/p/4594633.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!