系统级(system-wide)跨平台文件锁

来源:互联网 发布:米格走廊 知乎 编辑:程序博客网 时间:2024/05/01 09:19

不同于 msvcrt 和 fcntl 锁的实现,该锁是夸平台的 原子操作的文件锁。

FileLock类原码:

import osimport timeimport errno class FileLockException(Exception):    pass class FileLock(object):    """ A file locking mechanism that has context-manager support so         you can use it in a with statement. This should be relatively cross        compatible as it doesn't rely on msvcrt or fcntl for the locking.    """     def __init__(self, file_name, timeout=10, delay=.05):        """ Prepare the file locker. Specify the file to lock and optionally            the maximum timeout and the delay between each attempt to lock.        """        self.is_locked = False        self.lockfile = os.path.join(os.getcwd(), "%s.lock" % file_name)        self.file_name = file_name        self.timeout = timeout        self.delay = delay      def acquire(self):        """ Acquire the lock, if possible. If the lock is in use, it check again            every `wait` seconds. It does this until it either gets the lock or            exceeds `timeout` number of seconds, in which case it throws             an exception.        """        start_time = time.time()        while True:            try:                self.fd = os.open(self.lockfile, os.O_CREAT|os.O_EXCL|os.O_RDWR)                break;            except OSError as e:                if e.errno != errno.EEXIST:                    raise                 if (time.time() - start_time) >= self.timeout:                    raise FileLockException("Timeout occured.")                time.sleep(self.delay)        self.is_locked = True      def release(self):        """ Get rid of the lock by deleting the lockfile.             When working in a `with` statement, this gets automatically             called at the end.        """        if self.is_locked:            os.close(self.fd)            os.unlink(self.lockfile)            self.is_locked = False      def __enter__(self):        """ Activated when used in the with statement.             Should automatically acquire a lock to be used in the with block.        """        if not self.is_locked:            self.acquire()        return self      def __exit__(self, type, value, traceback):        """ Activated at the end of the with statement.            It automatically releases the lock if it isn't locked.        """        if self.is_locked:            self.release()      def __del__(self):        """ Make sure that the FileLock instance doesn't leave a lockfile            lying around.        """        self.release()

测试用例

lock1.py

if __name__ == '__main__':    with FileLock("../tox.ini", timeout=10) as lock:                ff=open('../tox.ini','a')        ff.write("lock1")        time.sleep(30)

lock2.py

    with FileLock("../tox.ini", timeout=10) as lock:        ff=open('../tox.ini','a')        ff.write("lock2")


原创粉丝点击