使用 python 文件启动的跟踪应用程序

Tracking application launched with a python file

我遇到过这样一种情况,我认为这样做是个好主意 为我倾向于运行几个实例的应用程序创建一个启动器 的。这是为了确保我和应用程序能够访问想要的 可为每个实例提供和设置的环境变量。

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()

我希望能够跟踪应用程序,是否将 pids 转储到文件中并 当进程关闭时删除它们?我是否启动了我沟通的服务 与?

总体上对编程还很陌生,我不知道我是否漏掉了一个术语 用行话或只是想错了。但我正在阅读守护进程和 跟踪应用程序的服务,但无法提出适当的建议 回答。简而言之,有点迷失了如何处理它。

这是一个代码示例,可帮助说明它如何为您工作。

请注意,您可以在宿主脚本中实时捕获进程的标准输出;如果您 运行 的程序使用控制台,这可能会有用。

(作为示例的旁注:您可能想要更改 IP 地址:这些来自我的内部网络。请善待您可能想要使用的任何外部站点。启动数千个进程同一个目标可能会被视为敌对姿态。)

(关于这个例子的附加说明:可以想象,在评估输出管道时我会丢失一些时间样本......如果子进程将它零碎地写入控制台,可以想象我可能偶尔会完全按照中途完成的方式捕获它 - 这意味着我可能会得到 "time=xxms" 语句的一半,导致 RE 错过它。我在检查这种可能性方面做得很差(即我不能为示例而烦恼)。这是 multiprocess/multithreaded 编程的危险之一,如果你经常这样做,你需要注意它。)

# 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()

你所做的似乎已经很合理了。我可能会把它扩展成这样:

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()