Pourquoi mon « sous-processus » Python se bloque-t-il lors de la lecture de la sortie d'un programme C utilisant « for line in iter(process.stdout.readline, \'\') » ?

Mary-Kate Olsen
Libérer: 2024-11-18 05:23:02
original
662 Les gens l'ont consulté

Why Does My Python `subprocess` Hang When Reading Output from a C Program Using `for line in iter(process.stdout.readline, '')`?

Le sous-processus Python se bloque avec "for line in iter"

Dans ce scénario, le script Python est destiné à exécuter un programme C et à recevoir sa sortie. Cependant, le script se bloque à la ligne "for line in iter(process.stdout.readline, '')".

Le problème de mise en mémoire tampon

Le problème vient de un problème de mise en mémoire tampon. Dans les programmes C, stdout est généralement mis en mémoire tampon lorsque la sortie est redirigée. Cela signifie que la sortie est mise en mémoire tampon jusqu'à ce qu'une certaine quantité soit écrite ou qu'une nouvelle ligne soit rencontrée.

Dans le programme C, chaque itération de la boucle while imprime "2000" et reste en veille pendant une seconde. Puisqu'aucune nouvelle ligne n'est imprimée, la sortie est mise en mémoire tampon.

Pour la ligne dans le numéro Iter

En Python, subprocess.stdout.readline() lit la sortie standard de l'enfant processus et renvoie une ligne. La boucle "for line in iter()" parcourt les lignes renvoyées par readline().

Cependant, comme la sortie du programme C n'est pas vidée en raison de la mise en mémoire tampon, il n'y a aucune ligne à lire à ce moment-là. où le script Python entre dans la boucle. Par conséquent, le script attend indéfiniment sur cette ligne.

Solutions

Correction de la mise en mémoire tampon dans le programme C

  • setvbuf() : Le programme C peut utiliser setvbuf() pour forcer la mise en mémoire tampon des lignes pour sortie standard. Cela garantira que chaque ligne est vidée immédiatement après l'impression.
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
Copier après la connexion
  • Utilitaire stdbuf : L'utilitaire stdbuf peut être utilisé pour envelopper le programme C et modifier son mise en mémoire tampon comportement.
stdbuf -oL ./main
Copier après la connexion

Pseudo-TTY

  • Module Pty : Le module pty peut être utilisé pour créer un pseudo-TTY qui fait croire au programme C qu'il s'exécute de manière interactive. Dans ce mode, la sortie sera mise en mémoire tampon de ligne par défaut.
import pty
master_fd, slave_fd = pty.openpty()
process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT,
                bufsize=0, close_fds=True)
Copier après la connexion
  • Bibliothèque pexpect : La bibliothèque pexpect fournit une interface de niveau supérieur pour travailler avec ptys.
import pexpect
child = pexpect.spawn("./main")
for line in child:
    print line
Copier après la connexion

En appliquant l'une de ces solutions, le problème de mise en mémoire tampon sera résolu, permettant au script Python de lire le sortie du programme C comme prévu.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal