我遇到过一种情况,我认为这是一个好主意 为我倾向于运行多个实例的应用程序创建一个启动器 的。这是为了确保我和应用程序可以访问所需的 可以为每个实例提供和设置的环境变量。
import os
import subprocess
def launch():
"""
Launches application.
"""
# create environment
os.environ['APPLICATION_ENVIRON'] = 'usr/path'
# launch application
application_path = 'path/to/application'
app = subprocess.Popen([application_path])
pid = app.pid
app.wait()
print 'done with process: {}'.format(pid)
if __name__ == '__main__':
launch()
我希望能够跟踪应用程序,将pid转储到文件中 进程关闭时删除它们?我是否启动了与之通信的服务? 与?
一般来说,编程相当新,我不知道我是否错过了一个术语 在行话中或只是想错了。但我正在阅读Daemons和 跟踪应用程序的服务,无法提供适当的服务 回答。简而言之,有点失去了如何接近它。
答案 0 :(得分:1)
你所做的事情似乎已经合理了。我可能会把它扩展到这样的东西:
import os
import subprocess
def launch_app():
os.environ['APPLICATION_ENVIRON'] = 'usr/path'
application_path = 'path/to/application'
return subprocess.Popen([application_path])
def _purge_finished_apps(apps):
still_running = set()
for app in apps:
return_code = app.poll()
if return_code is not None:
print " PID {} no longer running (return code {})".format(app.pid, return_code)
else:
still_running.add(app)
return still_running
def ui():
apps = set()
while True:
print
print "1. To launch new instance"
print "2. To view all instances"
print "3. To exit, terminating all running instances"
print "4. To exit, leaving instances running"
opt = int(raw_input())
apps = _purge_finished_apps(apps)
if opt == 1:
app = launch_app()
apps.add(app)
print " PID {} launched".format(app.pid)
elif opt == 2:
if not apps:
print "There are no instances running"
for app in apps:
print " PID {} running".format(app.pid)
elif opt == 3:
for app in apps:
print "Terminating PID {}".format(app.pid)
app.terminate()
for app in apps:
app.wait()
print "PID {} finished".format(app.pid)
return
elif opt == 4:
return
if __name__ == "__main__":
ui()
答案 1 :(得分:0)
以下是一个代码示例,以帮助说明它如何适合您。
请注意,您可以在主机脚本中实时捕获进程中的stdout;如果您正在运行的程序使用控制台,这可能很有用。
(作为示例的旁注:您可能想要更改IP地址:这些来自我的内部网络。请对您可能想要使用的任何外部网站表示友好。使用相同的方式启动数千个进程目标可能被解释为敌对姿态。)
(关于这个例子的另一个注意事项:可以想象,在评估输出管道时,我会丢失一些时间样本...如果子进程将它逐个写入控制台,可以想象我偶尔会抓到它正如它在中途完成一样 - 这意味着我可能得到“time = xxms”声明的一半,导致RE错过它。我在检查这种可能性方面做得很差(即我不能为此烦恼)例如)。这是多进程/多线程编程的危险之一,如果你做得太多,你需要注意这一点。)
# Subprocessor.py
#
# Launch a console application repeatedly and test its state.
#
import subprocess
import re
NUMBER_OF_PROCESSES_TO_OPEN = 3
DELAY_BETWEEN_CHECKS = 5
CMD = "ping"
ARGS = ([CMD, "-n", "8", "192.168.0.60"], [CMD, "-n", "12", "192.168.0.20"], [CMD, "-n", "4", "192.168.0.21"])
def go():
processes = {}
stopped = [False, False, False]
samples = [0]*NUMBER_OF_PROCESSES_TO_OPEN
times = [0.0]*NUMBER_OF_PROCESSES_TO_OPEN
print "Opening processes..."
for i in range(NUMBER_OF_PROCESSES_TO_OPEN):
# The next line creates a subprocess, this is a non-blocking call so
# the program will complete it more or less instantly.
newprocess = subprocess.Popen(args = ARGS[i], stdout = subprocess.PIPE)
processes[i] = newprocess
print " process {} open, pid == {}.".format(i, processes[i].pid)
# Build a regular expression to work with the stdout.
gettimere = re.compile("time=([0-9]*)ms")
while len(processes) > 0:
for i, p in processes.iteritems():
# Popen.poll() asks the process if it is still running - it is
# a non-blocking call that completes instantly.
isrunning = (p.poll() == None)
data = p.stdout.readline() # Get the stdout from the process.
matchobj = gettimere.search(data)
if matchobj:
for time in matchobj.groups():
samples[i] += 1
times[i] = (times[i] * (samples[i] - 1) + int(time)) / samples[i]
# If the process was stopped before we read the last of the
# data from its output pipe, flag it so we don't keep messing
# with it.
if not isrunning:
stopped[i] = True
print "Process {} stopped, pid == {}, average time == {}".format(i, processes[i].pid, times[i])
# This code segment deletes the stopped processes from the dict
# so we don't keep checking them (and know when to stop the main
# program loop).
for i in range(len(stopped)):
if stopped[i] and processes.has_key(i):
del processes[i]
if __name__ == '__main__':
go()