一个lock file的python实现

如果多个进程,或者多个独立程序要写同一个文件,那么就存在大家同时写文件的可能,这就不妙了,数据可能会出问题。最近在网上找到一个开源的python实现,有效简洁,列出来分析下代码看看:

文件名:lockfile.py,内容如下,有部分注释加了中文,添加了一些注释。

import os

import time

import 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()

"""

#use as:

from filelock import FileLock

with FileLock("myfile.txt"):

# work with the file as it is now locked

print("Lock acquired.")

""" 用法比较有意思,使用with关键字。对with关键字来说,FileLock类先执行__enter__函数,然后,执行with块里的那些代码,执行完了之后,再执行__exit__函数,等价于相当于如下形式: try: 执行 __enter__的内容 执行 with_block. finally: 执行 __exit__内容 FileLock在__enter__函数独占式创建或打开一个文件,这个文件不会被其他程序或者进程再次创建或者打开,由此形成lock,执行完代码,在__exit__里,关闭并删除文件

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐