• 文件锁


    https://gavv.github.io/articles/file-locks/

    ----------------------------------

    File locking in Linux

    29 Jul 2016

    Table of contents


    Introduction

    File locking is a mutual-exclusion mechanism for files. Linux supports two major kinds of file locks:

    • advisory locks
    • mandatory locks

    Below we discuss all lock types available in POSIX and Linux and provide usage examples.


    Advisory locking

    Traditionally, locks are advisory in Unix. They work only when a process explicitly acquires and releases locks, and are ignored if a process is not aware of locks.

    There are several types of advisory locks available in Linux:

    • BSD locks (flock)
    • POSIX record locks (fcntl, lockf)
    • Open file description locks (fcntl)

    All locks except the lockf function are reader-writer locks, i.e. support exclusive and shared modes.

    Note that flockfile and friends have nothing to do with the file locks. They manage internal mutex of the FILE object from stdio.

    Reference:

    Common features

    The following features are common for locks of all types:

    • All locks support blocking and non-blocking operations.
    • Locks are allowed only on files, but not directories.
    • Locks are automatically removed when the process exits or terminates. It’s guaranteed that if a lock is acquired, the process acquiring the lock is still alive.

    Differing features

    This table summarizes the difference between the lock types. A more detailed description and usage examples are provided below.

     BSD lockslockf functionPOSIX record locksOpen file description locks
    Portability widely available POSIX (XSI) POSIX (base standard) Linux 3.15+
    Associated with File object [i-node, pid] pair [i-node, pid] pair File object
    Applying to byte range no yes yes yes
    Support exclusive and shared modes yes no yes yes
    Atomic mode switch no - yes yes
    Works on NFS (Linux) Linux 2.6.12+ yes yes yes

    File descriptors and i-nodes

    file descriptor is an index in the per-process file descriptor table (in the left of the picture). Each file descriptor table entry contains a reference to a file object, stored in the file table (in the middle of the picture). Each file object contains a reference to an i-node, stored in the i-node table (in the right of the picture).

    A file descriptor is just a number that is used to refer a file object from the user space. A file object represents an opened file. It contains things likes current read/write offset, non-blocking flag and another non-persistent state. An i-node represents a filesystem object. It contains things like file meta-information (e.g. owner and permissions) and references to data blocks.

    File descriptors created by several open() calls for the same file path point to different file objects, but these file objects point to the same i-node. Duplicated file descriptors created by dup2() or fork() point to the same file object.

    A BSD lock and an Open file description lock is associated with a file object, while a POSIX record lock is associated with an [i-node, pid] pair. We’ll discuss it below.

    BSD locks (flock)

    The simplest and most common file locks are provided by flock(2).

    Features:

    • not specified in POSIX, but widely available on various Unix systems
    • always lock the entire file
    • associated with a file object
    • do not guarantee atomic switch between the locking modes (exclusive and shared)
    • up to Linux 2.6.11, didn’t work on NFS; since Linux 2.6.12, flock() locks on NFS are emulated using fcntl() POSIX record byte-range locks on the entire file (unless the emulation is disabled in the NFS mount options)

    The lock acquisition is associated with a file object, i.e.:

    • duplicated file descriptors, e.g. created using dup2 or fork, share the lock acquisition;
    • independent file descriptors, e.g. created using two open calls (even for the same file), don’t share the lock acquisition;

    This means that with BSD locks, threads or processes can’t be synchronized on the same or duplicated file descriptor, but nevertheless, both can be synchronized on independent file descriptors.

    flock() doesn’t guarantee atomic mode switch. From the man page:

    Converting a lock (shared to exclusive, or vice versa) is not guaranteed to be atomic: the existing lock is first removed, and then a new lock is established. Between these two steps, a pending lock request by another process may be granted, with the result that the conversion either blocks, or fails if LOCK_NB was specified. (This is the original BSD behaviour, and occurs on many other implementations.)

    This problem is solved by POSIX record locks and Open file description locks.

    Usage example:

    #include <sys/file.h>
    
    // acquire shared lock
    if (flock(fd, LOCK_SH) == -1) {
        exit(1);
    }
    
    // non-atomically upgrade to exclusive lock
    // do it in non-blocking mode, i.e. fail if can't upgrade immediately
    if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
        exit(1);
    }
    
    // release lock
    // lock is also released automatically when close() is called or process exits
    if (flock(fd, LOCK_UN) == -1) {
        exit(1);
    }
  • 相关阅读:
    python中xrange和range的异同
    Python:使用threading模块实现多线程编程
    python Queue模块
    Python中pass语句的作用
    Python的作用域
    eclipse颜色配置
    protobuf
    python调试总结
    chardet安装
    Windows下搭建PHP开发环境
  • 原文地址:https://www.cnblogs.com/oxspirt/p/14705057.html
Copyright © 2020-2023  润新知