检查python脚本中运行的python脚本

时间:2015-04-08 16:43:46

标签: python linux unix

我正在运行一个python脚本,可能需要或可能不需要几个小时才能完成。

在我的python脚本的开头,我想检查这个python脚本是否已经运行。

如果它已经在运行,我想退出我刚刚开始的当前python。

例如:

python在凌晨1点开始运行直到凌晨3点 在凌晨2点开始另一个,却不知道它已经在运行。 我希望我的2AM python检查并退出,因为它已经在运行。

我怎么写这个python?


这是我试图锁定的内容..

try:
    l = lock.lock("/home/auto.py", timeout=600) # wait at most 10 minutes

except error.LockHeld:
    e = sys.exc_info()[0]
    logging.error("Error: " + str(e) + " at main gatering Stats")
    smtpObj.sendmail(sender, receivers, message + "Error: " + str(e) + " at main gatering stats")
    exit("Fail: " + str(e) + " at main gathering Stats")
else:
    l.release()

所以我认为这将等待10分钟,如果它仍在运行然后退出..如果它不再运行,则运行当前的python

1 个答案:

答案 0 :(得分:2)

您可以尝试使用带有r标志的lockfile-create命令重试指定的次数来捕获CalledProcessError并退出,-p标记将存储{ {1}}过程:

pid

运行带有上述代码的import os import sys from time import sleep from subprocess import check_call, CalledProcessError try: check_call(["lockfile-create", "-q","-p", "-r", "0", "-l", "my.lock"]) except CalledProcessError as e: print("{} is already running".format(sys.argv[0])) print(e.returncode) exit(1) # main body for i in range(10): sleep(2) print(1) check_call(["rm","-f","my.lock"]) 脚本,而其中一个脚本已在运行时输出以下内容:

test.py

选项

-q, - quiet

  

取消任何输出。成功或失败仅由退出状态指示。

-v, - verbose

  

启用诊断输出。

-l, - lock-name

  

不要将.lock附加到文件名。此选项适用于lockfile-create,lockfile-remove,lockfile-touch或lockfile-check。

-p, - use-pid

  

每当创建一个锁文件时,将当前进程ID(PID)写入lockfile,并在检查锁的有效性时使用该pid。有关更多信息,请参见lockfile_create(3)联机帮助页。此选项适用于lockfile-create,lockfile-remove,lockfile-touch和lockfile-check。

-o,--oneshot

  

触摸锁定并立即退出。此选项适用于lockfile-touch和mail-touchlock。如果没有提供,这些命令将永远运行,每分钟触摸一次,直到被杀死。

-r retry-count, - retry retry-count

  

尝试在放弃之前锁定文件名重试次数。每次尝试都会比最后一次尝试延迟一点(以5秒为增量),直到重试之间达到最大延迟一分钟。如果未指定retry-count,则默认值为9,如果所有9次锁定尝试都失败,则会在180秒(3分钟)后放弃。

<强>描述

  

lockfile_create函数以NFS安全方式创建锁文件。

     

如果flags设置为L_PID,则lockfile_create不仅会检查现有的锁文件,还会读取内容以查看它是否包含ASCII中的进程ID。如果是,则锁定文件仅在该进程仍然存在时才有效。

     

如果lockfile位于共享文件系统上,则它可能是由远程主机上的进程创建的。因此,进程ID检查是无用的,不应设置L_PID标志。在这种情况下,没有好的方法来查看锁定文件是否过时。因此,如果锁定文件超过5分钟,它将被删除。这就是提供lockfile_touch函数的原因:在持有锁时,需要通过调用lockfile_touch()定期刷新(每分钟左右)。

     

lockfile_check函数检查是否已存在有效的锁文件而不尝试创建新的锁文件。

     

最后,lockfile_remove函数删除了锁文件。

Algorithm

用于以原子方式创建锁文件的算法,即使是通过NFS,也是如下:

1

  

创建一个唯一文件。在printf格式中,文件名是.lk%05d%x%s。第一个参数(%05d)是当前进程ID。第二个参数(%x)由time(2)返回的值的4个次要位组成。最后一个参数是系统主机名。

2

  

然后使用link(2)创建lockfile。链接的返回值被忽略。

3

  

现在锁文件是stat()ed。如果统计失败,我们转到第6步。

4

  

将lockfile的stat值与临时文件的stat值进行比较。如果它们是相同的,我们就有锁。删除临时文件,并将值0(成功)返回给调用者。

5

  

检查现有的锁文件是否有效。如果它无效,则删除陈旧的锁定文件。

6

  

在重试之前,我们睡了n秒钟。 n最初为5秒,但在每次重试后,额外增加5秒,最多为60秒(增量退避)。然后我们转到第2步重试次数。

redhat 上似乎有一个名为lockfile-progs的等效包。

在Mac上,您可以使用lockfile并执行以下操作:

$ python  lock.py 
lock.py is already running
4

在您的情况下,使用套接字可能会起作用:

import os
import sys
from time import sleep
import os
from subprocess import Popen, CalledProcessError, check_call


p = Popen(["lockfile", "-r", "0", "my.lock"])
p.wait()
if p.returncode == 0:
    with open("my.pid", "w") as f:
        f.write(str(os.getpid()))
else:
    try:
        with open("my.pid") as f:
            # see if process is still running or lockfile
            # is left over from previous run.
            r = f.read()
            check_call(["kill", "-0", "{}".format(r)])
    except CalledProcessError:
        # remove old lock file and create new
        check_call(["rm", "-f", "my.lock"])
        check_call(["lockfile", "-r", "0", "my.lock"])
        # update pid
        with open("my.pid", "w") as out:
            out.write(str(os.getpid()))
        print("Deleted stale lockfile.")
    else:
        print("{} is already running".format(sys.argv[0]))
        print(p.returncode)
        exit(1)
# main body

for i in range(10):
    sleep(1)
    print(1)
check_call(["rm", "-f", "my.lock"])