def _lock(fileno):
"""Try to lock a file. Return True on success."""
# closing the file unlocks it, so we don't need to unlock here
if platform.system() == 'Windows':
try:
msvcrt.locking(fileno, msvcrt.LK_NBLCK, 10)
return True
except PermissionError:
return False
else:
try:
fcntl.lockf(fileno, fcntl.LOCK_EX | fcntl.LOCK_NB)
return True
# the docs recommend catching both of these
except (BlockingIOError, PermissionError):
return False
python类locking()的实例源码
def __enter__(self):
self.lockfile = open(self.fname, 'w')
while True:
try:
# Using non-blocking locks since green threads are not
# patched to deal with blocking locking calls.
# Also upon reading the MSDN docs for locking(), it seems
# to have a laughable 10 attempts "blocking" mechanism.
self.trylock()
return self
except IOError as e:
if e.errno in (errno.EACCES, errno.EAGAIN):
# external locks synchronise things like iptables
# updates - give it some time to prevent busy spinning
time.sleep(0.01)
else:
raise
def trylock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1)
def unlock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1)
def _trylock(lockfile):
fileno = lockfile.fileno()
msvcrt.locking(fileno, msvcrt.LK_NBLCK, 1)
def _unlock(lockfile):
fileno = lockfile.fileno()
msvcrt.locking(fileno, msvcrt.LK_UNLCK, 1)
def lock(self, no_wait=False):
import msvcrt
if no_wait:
op = msvcrt.LK_NBLCK
else:
op = msvcrt.LK_LOCK
self.fd.seek(0)
msvcrt.locking(self.fd, op, 1)
def unlock(self):
import msvcrt
self.fd.seek(0)
msvcrt.locking(self.fd, LK_UNLCK, 1)
# ---------------------------------------------------------------------------
# Functions
# ---------------------------------------------------------------------------
def trylock(self):
if self.lockfile is None or self.lockfile.closed:
self.lockfile = open(self.path, 'a')
try:
if os.name == 'nt':
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1)
else:
fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
return True
except IOError,e:
if e.errno in (errno.EACCES, errno.EAGAIN):
return False
raise
def release(self):
if os.name == 'nt':
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1)
else:
fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
if self.lockfile is not None:
self.lockfile.close()
self.lockfile = None
def _lock_file(self):
# Lock just the first byte
try:
msvcrt.locking(self.fp.fileno(), msvcrt.LK_NBLCK, 1)
except IOError:
raise LockError(self.fp.name)
def _unlock_file(self):
try:
self.fp.seek(0)
msvcrt.locking(self.fp.fileno(), msvcrt.LK_UNLCK, 1)
except IOError:
raise UnlockError(self.fp.name)
def trylock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1)
def unlock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1)
def _lock_file(self):
# Lock just the first byte
try:
msvcrt.locking(self.fp.fileno(), msvcrt.LK_NBLCK, 1)
except IOError:
raise LockError(self.fp.name)
def _unlock_file(self):
try:
self.fp.seek(0)
msvcrt.locking(self.fp.fileno(), msvcrt.LK_UNLCK, 1)
except IOError:
raise UnlockError(self.fp.name)
def trylock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1)
def unlock(self):
msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1)
def _lock_file(file, content):
msvcrt.locking(file.fileno(), msvcrt.LK_LOCK, len(content))
def locked_file(fd, no_wait=False):
"""
This function is intended to be used as a ``with`` statement context
manager. It wraps a ``FileLock`` object so that the locking and unlocking
of the file descriptor are automatic. With the ``locked_file()`` function,
you can replace this code:
.. python::
lock = FileLock(fd)
lock.acquire()
try:
do_something()
finally:
lock.release()
with this code:
.. python::
with locked_file(fd):
do_something()
:Parameters:
fd : int
Open file descriptor. The file must be opened for writing
or updating, not reading.
no_wait : bool
If ``False``, then ``locked_file()`` will suspend the calling
process if someone has the file locked. If ``True``, then
``locked_file()`` will raise an ``IOError`` if the file is
locked by someone else.
"""
locked = False
try:
lock = FileLock(fd)
lock.acquire(no_wait)
locked = True
yield lock
finally:
if locked:
lock.release()