Chinaunix首页 | 论坛 | 博客
  • 博客访问: 575370
  • 博文数量: 112
  • 博客积分: 5090
  • 博客等级: 大校
  • 技术积分: 1158
  • 用 户 组: 普通用户
  • 注册时间: 2005-08-19 22:21
文章分类

全部博文(112)

文章存档

2016年(1)

2015年(1)

2012年(1)

2011年(5)

2010年(7)

2009年(6)

2008年(18)

2007年(28)

2006年(16)

2005年(29)

我的朋友

分类: LINUX

2005-12-04 23:02:27

存个挡

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

有些程序利用诸如 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来更新你所有的文件
输入/输出。

     lock(fd);
     write_to(some_function_of(fd));
     flush_output_to(fd); /* 在去锁之前一定要冲洗输出 */
     unlock(fd);
     do_something_else;   /* 也许另外一个进程会更新它 */
     lock(fd);
     seek(fd, somewhere); /* 因为原来的文件指针已不安全 */
     do_something_with(fd);
     ...

一些有用的fcntl()封锁方法(为了简洁略去错误处理):


    #include
    #include
   
    read_lock(int fd)   /* 整个文件上的一个共享的文件锁 */
    {
        fcntl(fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET));
    }
   
    write_lock(int fd)  /* 整个文件上的一个排外文件锁 */
    {
        fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_SET));
    }
   
    append_lock(int fd) /* 一个封锁文件结尾的锁,
                           其他进程可以访问现有内容 */
    {
        fcntl(fd, F_SETLKW, file_lock(F_WRLCK, SEEK_END));
    }

前面所用的file_lock函数如下:

    struct flock* file_lock(short type, short whence)
    {
        static struct flock ret ;
        ret.l_type = type ;
        ret.l_start = 0 ;
        ret.l_whence = whence ;
        ret.l_len = 0 ;
        ret.l_pid = getpid() ;
        return &ret ;
    }

阅读(1670) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~