I\'m writing a Python script that may or may not (depending on a bunch of things) run for a long time, and I\'d like to make sure that multiple instances (started via cron)
This might be of help to you: lockfile
There is a recipe on ActiveState on creating lockfiles.
To generate the filename you can use os.getpid() to get the PID.
If you can use GPLv2, Mercurial has a module for that:
http://bitbucket.org/mirror/mercurial/src/tip/mercurial/lock.py
Example usage:
from mercurial import error, lock
try:
l = lock.lock("/path/to/lock", timeout=600) # wait at most 10 minutes
# do something
except error.LockHeld:
# couldn't take the lock
else:
l.release()
I believe you will find the necessary information here. The page in question refers to a package for building daemons in python: this process involves creating a PID lockfile.
I know this is an old thread, but I also created a simple lock which only relies on python native libraries:
import fcntl
import errno
class FileLock:
def __init__(self, filename=None):
self.filename = os.path.expanduser('~') + '/LOCK_FILE' if filename is None else filename
self.lock_file = open(self.filename, 'w+')
def unlock(self):
fcntl.flock(self.lock_file, fcntl.LOCK_UN)
def lock(self, maximum_wait=300):
waited = 0
while True:
try:
fcntl.flock(self.lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
return True
except IOError as e:
if e.errno != errno.EAGAIN:
raise e
else:
time.sleep(1)
waited += 1
if waited >= maximum_wait:
return False
You can try PID: https://pypi.org/project/pid/
As the documentation shows, you can lock a function simply adding the decorator @pidfile()
on the top of function/method name.
from pid.decorator import pidfile
@pidfile()
def main():
pass
if __name__ == "__main__":
main()
The default location for pidfile self check (the file who says if you can execute the code or not) is '/var/run'. You can change it as follows:
@pidfile(piddir='/path/to/a/custom/location')
For other params, see: https://github.com/trbs/pid/blob/95499b30e8ec4a473c0e6b407c03ce644f61c643/pid/base.py#L41
Unfortunatly, this lib's documentation is a little bit poor.