假设我们有一个很长的脚本:Foo.pyx
如果我执行两次,它们将同时运行。
如果我执行两次,如何终止第一个?
编辑:终止后面的那些也可以工作,我只想让一个实例随时运行。
答案 0 :(得分:2)
传统的POSIX答案是使用pidfile
:一个存储在一致位置的文件,该文件只保存过程的PID。
您希望存储PID的原因是,如果脚本被终止,程序的新副本将能够看到并接管,而不是错误地报告另一个副本已在运行。 (您可以使用os.kill
发送0信号;如果成功,则该过程存在。)
有些库可以帮您完成并获得所有细节,但是一个简单的版本是:
import os
import sys
PIDFILE = '/var/run/myscript.pid'
def is_running():
try:
with open(PIDFILE) as f:
pid = int(next(f))
return os.kill(pid, 0)
except Exception:
return False
if __name__ == '__main__':
if is_running():
print('Another copy is already running')
sys.exit(0)
with open(PIDFILE, 'w') as f:
f.write(f'{os.getpid()}\n')
您可能希望在实际代码中使用更清晰的错误处理,并且您需要考虑比赛,但我一直保持简单明了。 (如果你想真正做到这一点,你可能最好不要使用图书馆,或者自己思考所有问题,而不是从SO上复制代码。)
传统的Windows答案略有不同。在Windows上,很容易获得对退出时自动释放的文件或其他资源的强制独占锁定。事实上,这是默认情况下打开文件时会发生的事情 - 但不幸的是,这不是Python的open
所发生的事情,它不会允许共享。您可以使用PyWin32中的win32api
库或ctypes
来调用CreateFile
请求独占访问权限。如果由于文件被锁定而失败,则会运行另一个进程。
决定创建文件的位置也很重要。通常,您使用的是每用户临时目录而不是全局临时目录,这意味着每个用户可以运行一个程序副本,而不是整个系统的一个副本。
答案 1 :(得分:1)
脚本启动时,检查是否存在特定文件。一个好的名字选择是myscript.lock
,但任何名字都可以。
如果存在,脚本应立即退出。否则,请创建该名称的空文件并继续执行该脚本。然后在脚本完成时删除该文件。