对flock的理解

Posted shouzhuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对flock的理解相关的知识,希望对你有一定的参考价值。

有时候需要保证同时只能有一个进程存在, 类似singleton的概念. 这时候简单方法就是对文件尝试加锁, 加锁成功就继续, 否则退出

函数定义如下:

int flock(int fd, int operation);  // 第一个参数是fd
man-pages中对fd参数说明如下:
Locks  created  by  flock()  are associated with an open file table entry.  This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these descriptors.

锁是和内核的file-entry绑定, 因此指向相同file-entry的fd是共享一个锁的. 比如父子进程, 或者通过dup复制的fd, 由于指向相同file-entry, 因此共享一个锁.

这里就有一个问题:

假设两个进程A和B. 分别open lockfile. 两个fd指向不同的file-entry. 此时A和B进程对fd加锁, 锁并没有关联到相同file-entry. 可以推断, 两个锁应该独立, 无法做到互斥. 但实际测试发现, 当A成功加锁后, B加锁会失败. 也就是说锁并不是独立的, 猜测锁其实是和inode关联的.
如果A成功加锁后, 将lockfile删除再新建lockfile. 此时lockfile的inode已经改变, 再启动B进程可以成功加锁. 因此猜测应该是对的, man-pages中的说明不太准确.

正确说法是: lock是和inode关联的, 一个inode同时有多个file-entry, 每个file-entry可以有多个fd. 这些fd都共享一个锁的逻辑.
 struct inode {
    struct hlist_node   i_hash;
    struct list_head    i_list;
    struct list_head    i_sb_list;
    struct list_head    i_dentry;
    unsigned long       i_ino;
    atomic_t        i_count;
    umode_t         i_mode;
    unsigned int        i_nlink;
    uid_t           i_uid;
    gid_t           i_gid;
    dev_t           i_rdev;
    loff_t          i_size;
    struct timespec     i_atime;
    struct timespec     i_mtime;
    struct timespec     i_ctime;
    unsigned int        i_blkbits;
    unsigned long       i_blksize;
    unsigned long       i_version;
    unsigned long       i_blocks;
    unsigned short          i_bytes;
    unsigned char       i_sock;
    spinlock_t      i_lock; /* i_blocks, i_bytes, maybe i_size */
    struct semaphore    i_sem;
    struct rw_semaphore i_alloc_sem;
    struct inode_operations *i_op;
    struct file_operations  *i_fop; /* former ->i_op->default_file_ops */
    struct super_block  *i_sb;
    struct file_lock    *i_flock;  // 可以看到flock是和inode绑定的

以上是关于对flock的理解的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 File#flock 对独占锁发出非阻塞请求?

flock,lockf,flockfile,funlockfile

第二次检查后flock lock丢失

PHP使用flock实现文件加锁来防止多进程同时写入文件

需要特定的cron作业解释,使用flock -n + .lock文件+ / bin / bash

Linux文件锁flock