9
votes

Comment ferme le tuyau stdout lors de la tuerie d'un processus commencé avec Python Subprocess Popen?

Je me demande s'il est possible d'éteindre le tuyau de communication lorsque vous tuez un sous-processus démarré dans un fil différent. Si je n'appelle pas communique (), tuez () tuera comme prévu, terminer le processus après une seconde au lieu de cinq.

J'ai trouvé une discussion sur un problème similaire ICI , mais je n'ai aucune réponse réelle. Je suppose que je devais être capable de fermer le tuyau ou de tuer explicitement la sous-sous-traitement (qui est "sommeil" dans l'exemple) et tuez-la pour débloquer le tuyau.

J'ai aussi essayé de Trouvez la réponse à elle sur, mais je n'ai trouvé que Ce et < Un href = "https://stackoverflow.com/questions/1180606/Undre-SUBProcess-popen-for-process-with-large-Output"> Ce et Ce , qui ne traite pas directement de ce problème autant que je puisse dire (?).

Donc, la chose que je veux faire est de pouvoir exécuter une commande dans un deuxième fil et d'obtenir toute sa production, mais être capable de le tuer instantanément lorsque je désirais tellement. Je pourrais aller via un fichier et une queue qui ou similaire, mais je pense qu'il devrait y avoir une meilleure façon de le faire? xxx

Ceci est le script: < Pré> xxx

sortie xxx


1 commentaires

Lorsque process.kill () est appelé, ./ ascript.sh meurt mais le 5 à l'intérieur de l'intérieur. Intéressant, cependant, que Python ne retourne pas immédiatement après ./ ascript.sh meurt.


3 Réponses :


-1
votes

On dirait que vous pouvez être victime de la simultanéité à grains super grossiers de Python. Changez votre script à ceci: xxx pré>

puis la sortie devient: p> xxx pré>

Si l'ensemble du script a couru, l'heure serait de 10 ans. Donc, il semble que le fil de contrôle Python ne fonctionne pas réellement qu'après le jeu de Bash dort. De même, si vous modifiez votre script à ceci: p> xxx pré>

puis la sortie devient: p>

process: sleeping five

real    0m1.150s
user    0m0.010s
sys     0m0.020s


3 commentaires

Le sommeil dans l'exemple n'est qu'un espace réservé pour toute opération longue étant faite dans le script. La question est, comment puis-je récupérer le tuyau à fermer afin que le code ne s'accroche pas sur la communication ()? Alternativement, comment puis-je savoir quelles «sous-cutérières» pour tuer pour libérer le bloc?


Voulez-vous dire que c'est l'interprète mondial durable au travail? docs.python.org/ C-API / ...


Je ne sais pas si le problème est le gil ou une interaction avec la planification du système d'exploitation. Je sais juste que le python n'attend pas que le script Bash se termine, comme en témoigne mon exemple. Vous pouvez essayer de l'exécuter sur une mise en œuvre de Python alternative. Ce serait un bon diagnostic, sinon une solution pratique: python.org/dev/implementations



0
votes

Il me semble que le moyen le plus simple de le faire et que Sidesteep Les problèmes multithreading seraient de définir un drapeau de tuer du fil principal et de le vérifier dans le fil d'exécution de script juste avant la communication, tuant le script quand Le drapeau est vrai .


1 commentaires

En fait, c'est plus un problème de blocage de tuyaux qu'un problème de multithreading. J'ai besoin d'un fil différent pour que je puisse l'arrêter de quelque part. Si je fais "tuer" de la coquille, il tue le script et ses sous-processus. Le tuer de Python omet de le faire car il semble vouloir que le tuyau soit arrêté.



6
votes

Je pense que le problème est que le processus est ce processus.Kill () ne tue que le processus d'enfant immédiat (Bash), et non les sous-processus du script Bash.

Le problème et la solution sont décrits ici: P>

  • http://www.doughellmann.com/pymotw/subprocess/ # groupes de processus-sessions li>
  • Comment mettre fin à un sous-processus Python lancé avec Shell = Vrai li> ul>

    Utilisez popen (..., PREEXEC_FN = OS.SETSID) Pour créer un groupe de processus et OS.PGKILL pour tuer l'ensemble du groupe de processus. EG P>

    $ time python poc.py 
    process: sleeping five
    
    real    0m1.051s
    user    0m0.032s
    sys 0m0.020s
    

  • 0 commentaires