2016-07-26 25 views
0

Ich habe zwei Subprozesse in einem Python-Server-Skript ausgeführt. Der Zweck der Subprozesse ist das Streamen von Videos von meinem Raspberry Pi.Wie Subprozesse mit einem anderen Befehl beenden Python

Meine Frage ist, wie die Subprozesse beendet werden, wenn ein anderer Befehl an den Server gesendet wird. Ich verwende derzeit Popen(), um die Teilprozesse zu starten.

Dies ist mein Code für, wenn der Server den Befehl "startStream" erhält. Ich verwende Twisted-Bibliothek als Server-Protokoll.

class Echo(Protocol): 
    def connectionMade(self): 
     #self.transport.write("""connected""") 
     self.factory.clients.append(self) 
     print "clients are ", self.factory.clients 

    def connectionLost(self, reason): 
     self.factory.clients.remove(self) 

    def dataReceived(self, data): 
     print "data is ", data 

     if data == "startStream": 
      p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True) 
      pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True) 

Was ich möchte ist so etwas.

if data == "startStream": 
     p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True) 
     pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True) 
elif data == "stopStream": 
     os.kill(p.pid) 
     os.kill(pn.pid) 

Vielen Dank!

+1

'terminate()'? – BusyAnt

+0

Das Problem ist, dass p und pn nicht zugänglich ist, wenn stopStream aufgerufen wird. Ich bin es gewohnt, mit Java zu arbeiten, wo ich die Prozesse einfach als globale Variablen deklariert habe und dann von überall darauf zugreifen kann, aber anscheinend funktioniert das in Python nicht. – Oliver

+0

Auch das Modul hat kein Attribut beenden – Oliver

Antwort

1

Sie verpassen etwas Kontext hier, aber im Grunde wäre Server etwas tun:

while True: 
    data = wait_for_request() 
    if data == 'startStream': 
     p = subprocess.Popen("raspistill --nopreview -w 640 -h 480 -q 5 -o /tmp/stream/pic.jpg -tl 100 -t 9999999 -th 0:0:0 &", shell=True) 
     pn = subprocess.Popen("LD_LIBRARY_PATH=/usr/local/lib mjpg_streamer -i %s -o %s &" % (x,y), shell=True) 
    elif data == 'stopStream': 
     p.terminate() 
     pn.terminate() 

Der entscheidende Teil ist, dass Name p und pn in demselben Umfang vorhanden und deshalb sind sie zugänglich, ohne jede Art von globaler Staat. Wenn Ihre Codestruktur anders ist, müssen Sie sie in Frage stellen.

Da data_received seinen eigenen Bereich bei jedem Aufruf hat, müssen Sie einen Verweis auf Ihr Popen-Objekt auf andere Weise übergeben. Glücklicherweise können Sie Referenzen in der Klasseninstanz beibehalten.

def dataReceived(self, data): 
    if data=='startStream': 
     self.p = subprocess.Popen() # ... 
     self.pn = subprocess.Popen() # ... 
    elif data=='stopStream': 
     self.p.terminate() 
     self.pn.terminate() 

Popen.terminate ist von Python 2.6 zur Verfügung und sollte gut funktionieren - ich bin nicht sicher, was ist ein Thema in den Kommentaren der Frage.

+0

Siehe meinen aktualisierten Code. So sieht mein Servercode derzeit aus. – Oliver

+0

Auch wie oben erwähnt funktioniert terminate() nicht. – Oliver

+0

Ich kann es nicht zur Arbeit bringen. Was meinst du mit dem Verweis auf mein Popen-Objekt? – Oliver