我有一个蟒蛇守护进程运行作为我的web应用程序的一部分/我怎样可以快速检查,如果我的守护进程正在运行(使用python),如果没有,启动它?检查是否python脚本运行
我想这样做的修复守护进程的任何崩溃,所以脚本不必手动运行,它就会自动运行,因为它是所谓的,然后保持运行。
如何检查(使用python),如果我的脚本运行?
我有一个蟒蛇守护进程运行作为我的web应用程序的一部分/我怎样可以快速检查,如果我的守护进程正在运行(使用python),如果没有,启动它?检查是否python脚本运行
我想这样做的修复守护进程的任何崩溃,所以脚本不必手动运行,它就会自动运行,因为它是所谓的,然后保持运行。
如何检查(使用python),如果我的脚本运行?
删除一个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)
然后,你可以检查,看看是否该过程是通过检查,看是否/tmp/mydaemon.pid的内容是现有的进程中运行。 Monit(上面提到的)可以为你做这件事,或者你可以编写一个简单的shell脚本来使用ps的返回代码来检查它。
ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"
对于额外的信用,你可以使用的atexit模块,以确保你的程序在任何情况下清理其pidfile进程文件(当杀,异常升高等)。
忘记关闭文件后写入PID? – ibz 2010-07-12 04:58:57
由于对文件对象的引用永远不会实际存储,因此在write()调用完成后它不会保留引用计数。我不确定这是否被认为是Pythonic,但它工作得很好。 具体来说:将分配对象,调用write()方法,然后它将立即释放,这将为您关闭文件。 – 2010-07-13 03:37:06
如果程序中断,os.unlink()将不会执行,程序将不会再次运行,因为该文件存在。对 ? – 2011-05-28 17:00:42
我的Supervisor管理守护进程的大风扇。它是用Python编写的,所以有很多关于如何与Python进行交互或扩展的例子。为了您的目的,XML-RPC process control API应该很好地工作。
当然,从丹的例子是行不通的,因为它应该是。
事实上,如果脚本崩溃,上升异常,或者不干净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"))
这部分代码,我们把一个PID文件中的锁锁文件文件
pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()
该代码将检查相比,现有的正在运行的进程的PID的值。,避免了双重执行。
我希望这会有所帮助。
的技术是在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)
它是原子,如果你的进程被发送一个SIGKILL
您避免了锁文件躺在身边的问题可以read in the documentation for socket.close
当垃圾收集时,套接字会自动关闭。
其他的答案是伟大的东西像cron作业,但如果你正在运行一个后台程序,你应该像daemontools监控。
请看下面的例子来解决你的问题:
#!/usr/bin/python
# -*- coding: latin-1 -*-
import os, sys, time, signal
def termination_handler (signum,frame):
global running
global pidfile
print 'You have requested to terminate the application...'
sys.stdout.flush()
running = 0
os.unlink(pidfile)
running = 1
signal.signal(signal.SIGINT,termination_handler)
pid = str(os.getpid())
pidfile = '/tmp/'+os.path.basename(__file__).split('.')[0]+'.pid'
if os.path.isfile(pidfile):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, 'w').write(pid)
# Do some actual work here
while running:
time.sleep(10)
我建议这个脚本,因为它可以在一个时间才可以执行。
试试这个其他版本的
def checkPidRunning(pid):
'''Check For the existence of a unix pid.
'''
try:
os.kill(pid, 0)
except OSError:
return False
else:
return True
# Entry point
if __name__ == '__main__':
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp", __program__+".pid")
if os.path.isfile(pidfile) and checkPidRunning(int(file(pidfile,'r').readlines()[0])):
print "%s already exists, exiting" % pidfile
sys.exit()
else:
file(pidfile, 'w').write(pid)
# Do some actual work here
main()
os.unlink(pidfile)
使用bash,以寻找与当前脚本的名称的进程。没有额外的文件。
import commands
import os
import time
import sys
def stop_if_already_running():
script_name = os.path.basename(__file__)
l = commands.getstatusoutput("ps aux | grep -e '%s' | grep -v grep | awk '{print $2}'| awk '{print $2}'" % script_name)
if l[1]:
sys.exit(0);
要进行测试,添加
stop_if_already_running()
print "running normally"
while True:
time.sleep(3)
ps ax | grep processName
如果pycharm侑调试脚本始终退出
pydevd.py --multiproc --client 127.0.0.1 --port 33882 --file processName
,而不是开发自己的PID文件的解决方案(其中有更多的细微之处和你可能会想到的情况下),看看supervisord - 这是一个过程控制系统,使它ea sy将现有Python脚本的作业控制和守护进程行为封装起来。
试试这个:
#/usr/bin/env python
import os, sys, atexit
try:
# Set PID file
def set_pid_file():
pid = str(os.getpid())
f = open('myCode.pid', 'w')
f.write(pid)
f.close()
def goodby():
pid = str('myCode.pid')
os.remove(pid)
atexit.register(goodby)
set_pid_file()
# Place your code here
except KeyboardInterrupt:
sys.exit(0)
这里是比较有用的代码(有检查,如果恰好蟒蛇执行脚本):
#! /usr/bin/env python
import os
from sys import exit
def checkPidRunning(pid):
global script_name
if pid<1:
print "Incorrect pid number!"
exit()
try:
os.kill(pid, 0)
except OSError:
print "Abnormal termination of previous process."
return False
else:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
process_exist = os.system(ps_command)
if process_exist == 0:
return True
else:
print "Process with pid %s is not a Python process. Continue..." % pid
return False
if __name__ == '__main__':
script_name = os.path.basename(__file__)
pid = str(os.getpid())
pidfile = os.path.join("/", "tmp/", script_name+".pid")
if os.path.isfile(pidfile):
print "Warning! Pid file %s existing. Checking for process..." % pidfile
r_pid = int(file(pidfile,'r').readlines()[0])
if checkPidRunning(r_pid):
print "Python process with pid = %s is already running. Exit!" % r_pid
exit()
else:
file(pidfile, 'w').write(pid)
else:
file(pidfile, 'w').write(pid)
# main programm
....
....
os.unlink(pidfile)
这里是字符串:
ps_command = "ps -o command= %s | grep -Eq 'python .*/%s'" % (pid,script_name)
回报0如果“grep”成功,并且进程“python”正在与na一起运行我的脚本作为参数。
一个简单的例子,如果你只在寻找的过程形同虚设与否:
import os
def pname_exists(inp):
os.system('ps -ef > /tmp/psef')
lines=open('/tmp/psef', 'r').read().split('\n')
res=[i for i in lines if inp in i]
return True if res else False
Result:
In [21]: pname_exists('syslog')
Out[21]: True
In [22]: pname_exists('syslog_')
Out[22]: False
遇到了这个老问题寻找解决方案自己。
使用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'])
你肯定你wan't你的过程太让您的其他过程长达写在Python? – ojblass 2009-04-25 07:18:06
在Tendo中去吧,创建脚本的单例实例,因此如果脚本已经在运行,它将不会运行。 https://github.com/pycontribs/tendo – JasTonAChair 2016-02-21 07:54:51