确保Linux中应用程序的唯一实例
我正在用WxPython开发一个图形界面应用程序,但我不太确定怎么才能确保在同一台机器上只能运行一个副本。因为这个应用的特性,运行多个副本是没有意义的,而且会很快出错。在Windows系统下,我可以简单地创建一个命名的互斥锁(mutex),然后在启动时检查这个锁。不过,我不知道在Linux系统中有没有类似的功能可以做到这一点。
我希望找到一种方法,如果应用程序意外崩溃,这个锁能自动释放。我不想让用户因为我的程序崩溃而需要手动删除锁文件。
12 个回答
这是一个使用 fcntl
模块的完整锁定解决方案:
import fcntl
pid_file = 'program.pid'
fp = open(pid_file, 'w')
try:
fcntl.lockf(fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
# another instance is running
sys.exit(1)
正确的方法是使用建议性的锁定,也就是用 flock(LOCK_EX)
;在Python中,这个功能可以在fcntl
模块中找到。
跟进程ID文件(pidfiles)不同,这种锁在你的程序因为任何原因崩溃时会自动释放,不会出现和文件删除相关的竞争条件(因为释放锁并不需要删除文件),而且也不会有其他进程继承这个进程ID,从而看起来像是验证了一个过期的锁。
如果你想检测不干净的关闭情况,可以在获取锁后在文件中写一个标记(比如你的进程ID,传统做法),然后在干净关闭之前把文件的内容清空(在持有锁的情况下);这样,如果锁没有被持有而文件又不为空,就表示发生了不干净的关闭。
有几种常见的方法可以用来处理这个问题,其中一种就是使用信号量。我看到最常用的方法是,在程序启动时创建一个“pid锁文件”,这个文件里会包含正在运行的进程的pid(进程标识符)。如果程序启动时发现这个文件已经存在,就打开它,读取里面的pid,然后检查一下这个pid对应的进程是否还在运行。如果这个进程还在运行,就查看一下它的命令行参数,看看是不是你的程序。如果是的话,就退出程序;如果不是,就用你自己的pid覆盖这个文件。通常,这个pid文件的名字是应用程序名称.pid
。