2016-01-24 70 views
0

我遇到過這種情況,我認爲這是一個好主意,我想爲一個應用程序創建一個啓動程序,我傾向於運行多個實例 。這是爲了確保我和應用程序可以訪問所需的 環境變量,這些變量可以爲每個實例提供和設置。使用python文件啓動的跟蹤應用程序

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的文件和 刪除它們時,進程關閉?我是否啓動了一項服務,與 進行溝通?

對於一般的編程來說相當新穎,我不知道我是否在術語中丟失了術語 或者只是在想錯誤。但我正在讀守護進程和 服務跟蹤應用程序,並不能拿出一個合適的 答案。簡單地說,有點丟失如何接近它。

+0

有幾個問題:「我希望能夠跟蹤應用程序」 - 通過「跟蹤它們」是什麼意思? 「...我傾向於運行幾個實例」 - 你事先知道你想要運行多少?你可以讓你的Python腳本運行,並使用它的輸入來根據需要啓動更多的進程? –

+0

@TomDalton通過跟蹤我的意思是我希望能夠以某種方式與他們聯繫,並且無法知道我要啓動多少個實例。是的,那將是可能的。 – Arubertoson

回答

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

'poll'寫入「[s] et和* return *'returncode'屬性」。 – eryksun

+0

編輯代碼以反映上述見解;我始終認爲必須從returncode中提取值,所以感謝@eryksun指針。 – TPDMarchHare