Hallo,
ich habe seit einigen Monaten einen Radiowecker auf Basis des PI in Betrieb, dessen Python-Script alle paar Monate abstürzt. Nun habe ich das erste mal auch die Fehlermeldung des Scripts:
Traceback (most recent call last):
File "Wecker.py", line 73, in <module>
St.StateMachine()
File "/var/Wecker/States.py", line 130, in StateMachine
if (actTime-self.BrightTimeout<60 or self.Player.isStreamingActive()):
File "/var/Wecker/PlayerMPC.py", line 24, in isStreamingActive
p = subprocess.Popen(['mpc'],stdout=subprocess.PIPE)
File "/usr/lib/python2.7/subprocess.py", line 390, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 916, in _execute_child
self.pid = os.fork()
OSError: [Errno 12] Cannot allocate memory
Alles anzeigen
Ich nutze MPD/MPC als Player und prüfe mittels isStreamingActive(self) zyklisch mehrmals pro Sekunde, ob der Player aktiv ist und das Streaming läuft. Der relevante Code-Teil sieht so aus:
# -*- coding: utf-8 -*-
import os
import subprocess
class MPlayerClass:
#**********************
# Stream starten
#**********************
def Start(self):
devnull = open(os.devnull, 'w')
subprocess.Popen(['mpc','play','1'],stdout=devnull,stderr=devnull)
#**********************
# Stream stoppen
#**********************
def Stopp(self):
devnull = open(os.devnull, 'w')
subprocess.Popen(['mpc','stop'],stdout=devnull,stderr=devnull)
#**********************
# Stream pruefen
#**********************
def isStreamingActive(self):
p = subprocess.Popen(['mpc'],stdout=subprocess.PIPE)
p.wait()
out = p.stdout.read()
if (out.find('[playing]') == -1):
return False
else:
return True
Alles anzeigen
Der Fehler trat also beim zyklischen Aufruf von MPC als Subprocess auf. Konkret prüfe ich hier, ob die Ausgabe von MPC den String '[playing]' enthält.
Nach einigem Googeln habe ich nichts Konkretes gefunden, außer, dass wohl bei jedem popen-Aufruf etwas Speicher für irgendwas reserviert und evtl. nicht mehr freigegeben wird. Wirklich verstanden habe ich das aber nicht. Habe ich an der Stelle irgendwas unsauber umgesetzt? Geht das eleganter?
Muss ich das Objekt p irgendwie löschen/entsorgen, die PIPE irgendwie schließen?
Komme ich vielleicht eleganter an den aktuellen Status von MPD? Blöd finde ich hier nämlich auch, dass ich dieses p.wait() in meiner Hauptschleife drin habe. Aber ne bessere Möglichkeit kenne ich nicht.
Michael