La communication du sous-processus Python tue mon processus
-
21-12-2019 - |
Question
Pourquoi la communication tue-t-elle mon processus ?Je veux un processus interactif mais communicate fait quelque chose pour que je ne puisse plus prendre raw_input dans mon processus.
from sys import stdin
from threading import Thread
from time import sleep
if __name__ == '__main__':
print("Still Running\n")
x = raw_input()
i = 0
while ('n' not in x ) :
print("Still Running " + str(i) + " \r\n")
x = raw_input()
i += 1
print("quit")
print(aSubProc.theProcess.communicate('y'))
print(aSubProc.theProcess.communicate('y'))
exception!
self.stdin.write(input)
ValueError: I/O operation on closed file
La solution
communicate
et wait
Méthodes de Popen
objets, fermez le PIPE
après le retour du processus.Si vous souhaitez rester en communication avec le processus, essayez quelque chose comme ceci :
import subprocess
proc = subprocess.Popen("some_process", stdout=subprocess.PIPE, stdin=subprocess.PIPE)
proc.stdin.write("input")
proc.stdout.readline()
Autres conseils
Pourquoi la communication tue-t-elle mon processus ?
À partir des documents pour Popen.communicate(input=None, timeout=None)
:
Interagissez avec le processus :Envoyez les données à stdin.Lire les données depuis la sortie standard et
stderr, jusqu'à ce que la fin du fichier soit atteinte. Attendez la fin du processus. souligner le mien
Vous pouvez appeler .communicate()
juste une fois.Cela signifie que vous devez fournir toutes les entrées en même temps :
#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
p = Popen([sys.executable, 'child.py'], stdin=PIPE, stdout=PIPE)
print p.communicate(os.linesep.join('yyn'))[0]
Sortir
Still Running
Still Running 0
Still Running 1
quit
Notez les nouvelles lignes doublées :un de '\r\n'
et un autre de print
déclaration elle-même dans votre script pour le processus enfant.
La sortie montre que le processus enfant a reçu avec succès trois lignes d'entrée ('y'
, 'y'
, et 'n'
).
Voici un code similaire utilisant subprocess.check_output()
c'est input
paramètre de Python3.4 :
#!/usr/bin/env python3.4
import os
import sys
from subprocess import check_output
output = check_output(['python2', 'child.py'], universal_newlines=True,
input='\n'.join('yyn'))
print(output, end='')
Il produit le même résultat.
Si vous souhaitez fournir une entrée différente en fonction des réponses des processus enfants, utilisez pexpect
module ou ses analogues pour éviter les problèmes mentionnés dans Pourquoi ne pas simplement utiliser un tube (popen()) ?