Jos*_*unt 90 python daemon process
我有一个python守护程序作为我的Web应用程序的一部分运行/如果我的守护程序正在运行,我如何快速检查(使用python),如果没有,启动它?
我想以这种方式来修复守护进程的任何崩溃,因此脚本不必手动运行,它会在调用后立即自动运行然后保持运行.
如果我的脚本正在运行,我如何检查(使用python)?
ayc*_*dee 142
在Linux系统上使用的技术是使用域套接字:
import socket
import sys
import time
def get_lock(process_name):
# Without holding a reference to our socket somewhere it gets garbage
# collected when the function exits
get_lock._lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
try:
get_lock._lock_socket.bind('\0' + process_name)
print 'I got the lock'
except socket.error:
print 'lock exists'
sys.exit()
get_lock('running_test')
while True:
time.sleep(3)
Run Code Online (Sandbox Code Playgroud)
它是原子的,并且避免了如果您的进程被发送SIGKILL而存在锁定文件的问题
您可以在文档中阅读socket.close这些套接字在收集垃圾时自动关闭.
Dan*_*dey 88
在某处删除一个pidfile(例如/ tmp).然后,您可以通过检查文件中的PID是否存在来检查进程是否正在运行.完全关闭时不要忘记删除文件,并在启动时检查它.
#/usr/bin/env python
import os
import sys
pid = str(os.getpid())
pidfile = "/tmp/mydaemon.pid"
if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
file(pidfile, 'w').write(pid)
try:
# Do some actual work here
finally:
os.unlink(pidfile)
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过检查/tmp/mydaemon.pid的内容是否为现有进程来检查进程是否正在运行.Monit(如上所述)可以为您完成此操作,或者您可以使用ps的返回代码编写一个简单的shell脚本来检查它.
ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"
Run Code Online (Sandbox Code Playgroud)
为了额外的功劳,你可以使用atexit模块来确保你的程序在任何情况下(杀死,引发异常等)清理它的pid文件.
Dec*_*cko 17
该PID库可以做的正是这一点.
from pid import PidFile
with PidFile():
do_something()
Run Code Online (Sandbox Code Playgroud)
它还将自动处理pidfile存在但进程未运行的情况.
小智 10
当然Dan的例子不会像它应该的那样工作.
实际上,如果脚本崩溃,引发异常,或者不清除pid文件,脚本将多次运行.
我建议以下来自另一个网站:
这是为了检查是否已存在锁定文件
\#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
#if the lockfile is already there then check the PID number
#in the lock file
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
pidfile.seek(0)
old_pid = pidfile.readline()
# Now we check the PID from lock file matches to the current
# process PID
if os.path.exists("/proc/%s" % old_pid):
print "You already have an instance of the program running"
print "It is running as process %s," % old_pid
sys.exit(1)
else:
print "File is there but the program is not running"
print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))
Run Code Online (Sandbox Code Playgroud)
这是我们将PID文件放入锁定文件的代码的一部分
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()
Run Code Online (Sandbox Code Playgroud)
此代码将检查pid与现有运行进程相比的值,避免双重执行.
我希望它会有所帮助.
有无数的选择。一种方法是使用为您执行此类调用的系统调用或 python 库。另一种是简单地产生一个过程,如:
ps ax | grep processName
Run Code Online (Sandbox Code Playgroud)
并解析输出。很多人选择这种方法,在我看来这不一定是一种坏方法。
自己遇到了这个老问题,正在寻找解决方案。
使用psutil:
import psutil
import sys
from subprocess import Popen
for process in psutil.process_iter():
if process.cmdline() == ['python', 'your_script.py']:
sys.exit('Process found: exiting.')
print('Process not found: starting it.')
Popen(['python', 'your_script.py'])
Run Code Online (Sandbox Code Playgroud)
我的解决方案是检查在Windows和ubuntu linux上测试过的进程和命令行参数
import psutil
import os
def is_running(script):
for q in psutil.process_iter():
if q.name().startswith('python'):
if len(q.cmdline())>1 and script in q.cmdline()[1] and q.pid !=os.getpid():
print("'{}' Process is already running".format(script))
return True
return False
if not is_running("test.py"):
n = input("What is Your Name? ")
print ("Hello " + n)
Run Code Online (Sandbox Code Playgroud)