2015-01-15 8 views
0

Windows에서 간단한 서버를 실행하고 간단한 GUI로 프로세스를 출력하고 있습니다.연속 배치 프로세스 내에서 두 번째 프로세스 실행 python

이 프로세스를 계속 실행하고 싶지만 동일한 터미널에서 다른 간단한 프로세스를 실행하고 싶습니다.

터미널에 프로세스를 더 추가하려고하면 서버가 계속 실행되지만 서버는 계속 실행되지만 명령 자체는 서버에서 실행되지 않습니다.

나는 5 초마다

#runserver.bat 
:loop 
@echo OFF 
@echo %time% 
ping localhost -n 6 > nul 
goto loop 

스크립트가 UI가 잠길 경우에도 종료 될 때까지 출력은 무기한으로 한 번만 호출 실행을 실행하는 서버를 시뮬레이션하는 간단한 배치 프로세스가 있습니다.

from threading import Thread 
from subprocess import Popen, PIPE, STDOUT, call 
from Tkinter import * 
from ttk import Frame, Button, Label, Style 
from Queue import Queue, Empty 
from collections import deque 
from itertools import islice 


def iter_except(function, exception): 
    try: 
     while True: 
      yield function() 
    except exception: 
     return 

class buildGUI(Frame): 

    def __init__(self, parent): 
     Frame.__init__(self, parent)   
     self.parent = parent   
     self.initUI() 

    def initUI(self): 

     self.proc = Popen("runserver.bat", shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT) 

     q = Queue() 
     t = Thread(target=self.reader_thread, args=[q]).start() 

     #setup UI  
     self.parent.title("Server Manager") 
     self.style = Style() 
     self.style.theme_use("default") 
     self.pack(fill=BOTH, expand=1) 

     self.columnconfigure(1, weight=1) 
     self.columnconfigure(3, pad=7) 
     self.rowconfigure(7, weight=1) 
     self.rowconfigure(5, pad=2) 

     self.loglbl = Label(self, text="Log") 
     self.loglbl.grid(sticky=W, column=1, pady=4, padx=5) 

     self.var = StringVar() 
     self.playerlbl = Label(self, text=0, textvariable=self.var) 
     self.playerlbl.grid(sticky=W, column=0, row=5, pady=4, padx=5) 

     self.area = Text(self) 
     self.area.grid(row=1, column=1, columnspan=2, rowspan=10, 
      padx=5, sticky=E+W+S+N) 

     self.dirbtn = Button(self, text="dir") 
     self.dirbtn.grid(row=3, column=0,pady=4, padx=5) 
     self.dirbtn.bind("<Button-1>", self.runProcess) 

     self.updateUI(q) 

    def runProcess(self, event): 
      print "pressed" 
      self.proc.communicate("dir") 

    def reader_thread(self, q): 
     #add output to thread 
     for line in iter(self.proc.stdout.readline, b''): 
      q.put(line) 

    def updateUI(self, q): 
     #use deque to discard lines as they are printed to the UI, 
     for line in deque(islice(iter_except(q.get_nowait, Empty), None), maxlen=5): 
      if line is None: 
       return # stop updating 
      else: 
       self.area.insert(END,line) # update GUI 

     self.parent.after(1000, self.updateUI, q) # schedule next update 

def main(): 

    root = Tk() 
    root.geometry("850x450+100+100") 
    app = buildGUI(root) 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

내가 stdin.writecommunicate()를 교체 시도했지만 모두 내가 누군가가 기존의 과정에서 프로세스를 실행하는 데 필요한 예제를 찾을 수 없어

def runProcess(self, event): 
     print "pressed" 
     self.proc.communicate("dir") 

UI를 잠그고, 대부분의 예제는 프로세스가 종료 될 수 있거나 다른 프로세스가 완료 될 때 프로세스를 실행할 수 있으므로 폴 또는 종료를 사용할 수 있다고 가정합니다.

열린 프로세스로 읽는 유일한 예는 프로세스를 종료하는 것처럼 보입니다. [대답은/(https://stackoverflow.com/a/16770371)

내가 추가는 popen 명령을 호출 시도했다, 그러나 이것은 단지 GUI를 차단하지 않고 두 번째 프로세스를 실행하려면 서버

+0

코드는 [내 예제] (http://stackoverflow.com/questions/15362372/display-realtime-output-of-a-subprocess-in-a-tkinter-widget#comment24334740_15362372)를 기준으로 이미 보여줍니다. GUI를 차단하지 않고 서브 프로세스에서 "실시간"으로 출력을 얻는 방법. 코드를 읽고 선이 무엇을하는지 이해하지 못한다면; 질문하기 – jfs

+0

자식 프로세스의 출력을 버리고 싶지 않다면,'deque','islice'를 제거하십시오. – jfs

답변

0

에 의해 무시 될 것으로 보인다 정확히 의 두 번째 스레드를 시작은 첫 번째 프로세스와 동일한 방식으로 수행됩니다.

출력을 "실시간"으로 캡처 할 필요가없는 경우 코드가 더 간단 할 수 있습니다. subprocess.call() 또는 proc.communicate()을 다른 스레드에서 호출하십시오.

출력을 모두 캡처 할 필요가 없으면 오랫동안 차단하지 않는 Popen()을 사용하여 하위 프로세스를 시작할 수 있습니다.

+0

서버 자체에서 명령을 호출하려고 할 때 명령을 동일하게 실행할 필요가 없습니까? 실? 'subprocess.call()'이 dir 명령을 성공적으로 호출하여 터미널에 출력했지만 서버 특정 명령을 호출 할 수 없었습니다. 'proc.communicate()'사용하기 나는 서버에서 호출을 보지 못했고 별도의 스레드가 도움이 될지 확신하지 못합니다. –

+0

@ShaunFallis :''runserver.bat ''자식 프로세스를 시작한 하나의 GUI 스레드가 있습니다. 자식 프로세스는 서버로부터 출력을 읽는 독자 스레드입니다. * "서버의 명령 호출"*이 무엇을 의미합니까? 관련 없음 : 터미널에서 출력을보고 싶지 않으면'os.devnull' 파일로 리디렉션하십시오 ('call (..., stdout = DEVNULL, stderr = subprocess.STDOUT)') – jfs

+0

서버는 단순한 게임 서버입니다. 서버가 실행되는 동안 명령 프롬프트에 'player'를 입력하면 활성 플레이어 목록이 표시됩니다. 이것은 전체 출력을 GUI로 전환하면서 복제하려고 시도합니다. –