2017-09-27 7 views
0

Essayer d'utiliser des sous-processus Python pour lire de l'audio sur un Raspberry Pi et tuer le sous-processus lorsqu'un bouton GPIO est connecté. Le problème que j'ai est que le sous-processus ne tue pas quand il y a une commande de sous-processus Popen.wait() entre les fichiers de playback. S'il n'y a qu'un seul fichier à jouer, il n'est pas nécessaire d'attendre que cela se termine, et une commande p.kill() fonctionne très bien. Dès qu'un p.wait() est inséré pour que les fichiers ne se jouent pas les uns sur les autres, Popen.kill() ne fonctionne plus.Comment tuer un sous-processus Python pendant qu'il attend de finir?

Déjà essayé en utilisant os.kill() dans Kill a running subprocess call. Impossible de trouver d'autres ressources sur le comportement des sous-processus sous Popen.wait(). Je cherche un moyen de forcer la fonction aplay dans le code ci-dessous pour fermer sur un bouton appuyer à tout moment au cours des trois commandes play_wav dans le deuxième extrait de code au lieu d'avoir une seule commande play_wav.

est ici la fonction play_wav utilisant subprocess.Popen():

# play wav file on the attached system sound device 
def play_wav(wav_filename): 
    global p 
    msg = "playing " + wav_filename 
    logger.debug(msg) 
    p = subprocess.Popen(
     ['aplay','-i','-D','plughw:1', wav_filename], 
     stdin = subprocess.PIPE, 
     stdout = subprocess.PIPE, 
     stderr = subprocess.STDOUT, 
     shell = False 
    ) 

Voici un extrait de code appelant la fonction play_wav:

# determine what to do when a button is pressed 
def button_pressed(channel): 
    global MENU 
    btnval = readadc(0, SPICLK, SPIMOSI, SPIMISO, SPICS) # check value of ADC 
    if btnval > 980: # 1 
     if p.poll() == None: 
      p.kill() 
     if MENU == 1: 
      play_wav("/media/pi/WONDERPHONE/prompts/en/Menu1.wav") 
      p.wait() 
      play_wav("/media/pi/WONDERPHONE/stories/1/PersonalStory.wav") 
      p.wait() 
      play_wav("/media/pi/WONDERPHONE/prompts/en/returntomain.wav") 

Comment je vérifie appuie sur un bouton:

GPIO.add_event_detect(PRESSED, GPIO.RISING, callback=button_pressed, bouncetime=500) # look for button presses 

Répondre

0

Vous pouvez utiliser le terminal pour cela. ps aux | grep taskName kill -9 taskid sudo

1

à partir du module subprocess docs:

Popen.wait()

Attendez processus enfant de mettre fin. Définir et renvoyer l'attribut de code retour. Avertissement - Cette situation sera bloquée lors de l'utilisation de stdout = PIPE et/ou stderr = PIPE et le processus enfant génère suffisamment de sortie dans un canal de telle sorte qu'il bloque l'attente du tampon de canal du système d'exploitation pour accepter plus de données. Utilisez communic() pour éviter cela.

Essayez d'utiliser communicate() avant tuez le sous-processus