Maison >développement back-end >Tutoriel Python >Pourquoi Python `subprocess.readline()` se bloque-t-il lors de la diffusion de la sortie Ruby et comment puis-je y remédier ?

Pourquoi Python `subprocess.readline()` se bloque-t-il lors de la diffusion de la sortie Ruby et comment puis-je y remédier ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-21 00:21:09233parcourir

Why Does Python `subprocess.readline()` Hang When Streaming Ruby Output, and How Can I Fix It?

Le sous-processus Python Readlines() provoque des blocages dans le flux

Le but du code est de diffuser un fichier Ruby et de sortir son contenu progressivement. Alors que l'aspect streaming est atteint, nous rencontrons un problème où readline() se bloque indéfiniment, empêchant toute exécution ultérieure.

Exploration des solutions potentielles

L'utilisation de pty dépend de la plate-forme approche qui suppose la prise en charge de Linux ou d’un système d’exploitation compatible. Cependant, compte tenu des problèmes de compatibilité multiplateforme :

  • Pexpect : Cette bibliothèque pourrait fournir une méthode alternative pour gérer l'interaction des processus.
  • stdbuf : Cet outil permet la mise en mémoire tampon de ligne en mode non interactif, permettant une sortie immédiate.
  • Modifié Approche pty :

Une amélioration suggérée à la mise en œuvre pty existante :

import errno
import os
import pty
from subprocess import Popen, STDOUT

master_fd, slave_fd = pty.openpty()  # provide tty to enable line-buffering on ruby's side
proc = Popen(['ruby', 'ruby_sleep.rb'],
             stdin=slave_fd, stdout=slave_fd, stderr=STDOUT, close_fds=True)
os.close(slave_fd)
try:
    while 1:
        try:
            data = os.read(master_fd, 512)
        except OSError as e:
            if e.errno != errno.EIO:
                raise
            break  # EIO means EOF on some systems
        else:
            if not data:  # EOF
                break
            print('got ' + repr(data))
finally:
    os.close(master_fd)
    if proc.poll() is None:
        proc.kill()
    proc.wait()
print("This is reached!")

Conclusion

Les trois solutions proposées résolvez le problème en activant la mise en mémoire tampon de ligne pour une sortie immédiate, tandis que l'approche pty révisée garantit une gestion gracieuse des entrées et des sorties tout en maximisant la compatibilité de la plate-forme.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn