的Python:用于创建基于PID的锁定文件模块?(Python: module for creat

2019-07-18 12:22发布

我正在写,可能会或可能不会(取决于一堆东西),运行时间长的Python脚本,我想,以确保多个实例(通过cron启动)不会对每个人的脚趾步骤。 这样做的合乎逻辑的方式似乎是一个基于PID的锁定文件......但是我不想,如果已经有代码这样做是为了重新发明轮子。

那么,有没有一个Python模块在那里将管理一个基于PID的锁定文件的细节?

Answer 1:

如果你可以使用了GPLv2,水银有一个模块:

http://bitbucket.org/mirror/mercurial/src/tip/mercurial/lock.py

实例:

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


Answer 2:

这可能是对你有所帮助: 锁定文件



Answer 3:

我相信你会找到需要的信息在这里 。 有问题的页面是指包在python构建守护进程:该进程涉及创建PID锁定文件。



Answer 4:

我已经与所有那些漂亮的不满,所以我写了这一点:

class Pidfile():
    def __init__(self, path, log=sys.stdout.write, warn=sys.stderr.write):
        self.pidfile = path
        self.log = log
        self.warn = warn

    def __enter__(self):
        try:
            self.pidfd = os.open(self.pidfile, os.O_CREAT|os.O_WRONLY|os.O_EXCL)
            self.log('locked pidfile %s' % self.pidfile)
        except OSError as e:
            if e.errno == errno.EEXIST:
                pid = self._check()
                if pid:
                    self.pidfd = None
                    raise ProcessRunningException('process already running in %s as pid %s' % (self.pidfile, pid));
                else:
                    os.remove(self.pidfile)
                    self.warn('removed staled lockfile %s' % (self.pidfile))
                    self.pidfd = os.open(self.pidfile, os.O_CREAT|os.O_WRONLY|os.O_EXCL)
            else:
                raise

        os.write(self.pidfd, str(os.getpid()))
        os.close(self.pidfd)
        return self

    def __exit__(self, t, e, tb):
        # return false to raise, true to pass
        if t is None:
            # normal condition, no exception
            self._remove()
            return True
        elif t is PidfileProcessRunningException:
            # do not remove the other process lockfile
            return False
        else:
            # other exception
            if self.pidfd:
                # this was our lockfile, removing
                self._remove()
            return False

    def _remove(self):
        self.log('removed pidfile %s' % self.pidfile)
        os.remove(self.pidfile)

    def _check(self):
        """check if a process is still running

the process id is expected to be in pidfile, which should exist.

if it is still running, returns the pid, if not, return False."""
        with open(self.pidfile, 'r') as f:
            try:
                pidstr = f.read()
                pid = int(pidstr)
            except ValueError:
                # not an integer
                self.log("not an integer: %s" % pidstr)
                return False
            try:
                os.kill(pid, 0)
            except OSError:
                self.log("can't deliver signal to %s" % pid)
                return False
            else:
                return pid

class ProcessRunningException(BaseException):
    pass

使用这样的事情:

try:
    with Pidfile(args.pidfile):
        process(args)
except ProcessRunningException:
    print "the pid file is in use, oops."


Answer 5:

我知道这是一个古老的线程,但我也创建了一个简单的锁,只有依靠蟒蛇本地库:

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


Answer 6:

有一种创造的lockfiles上ActiveState的配方 。

要生成的文件名,你可以使用os.getpid()来获得PID。



文章来源: Python: module for creating PID-based lockfile?