Maison >développement back-end >C++ >Comment exécuter des processus enfants avec Piped Stdin et Stdout sous Linux ?

Comment exécuter des processus enfants avec Piped Stdin et Stdout sous Linux ?

DDD
DDDoriginal
2024-11-19 15:27:03835parcourir

How to Execute Child Processes with Piped Stdin and Stdout in Linux?

Exécution de processus enfants avec canalisation Stdin et Stdout sous Linux

Sous Linux, les tâches nécessitant l'exécution de processus enfants avec entrée standard canalisée (stdin ) et la sortie standard (stdout) peuvent être réalisées via divers appels système ou fonctions POSIX. Plus précisément, pour Linux 3.0 et supérieur, l'approche recommandée implique l'utilisation de pipe(), fork(), execve() et dup2().

Présentation de la solution

  1. Créer des tuyaux :

    • Utilisez pipe() pour créer deux tuyaux : un pour stdin (aStdinPipe) et un pour stdout (aStdoutPipe).
  2. Processus Fork :

    • Utilisez fork() pour créer un processus enfant.
  3. Redirection IO dans l'enfant :

    • Dans le processus enfant, utilisez dup2() pour rediriger stdin de aStdinPipe[PIPE_READ] vers le stdin de l'enfant et stdout/ stderr vers aStdoutPipe[PIPE_WRITE].
  4. Fermer les tuyaux inutilisés :

    • Fermer les descripteurs de fichiers inutilisés de aStdinPipe[PIPE_READ ] et aStdoutPipe[PIPE_WRITE] dans le processus parent.
  5. Exécution enfant :

    • Utilisez execve() dans le processus enfant pour exécuter la commande souhaitée.
  6. Communication IO :

    • Dans le processus parent, écrivez les données dans aStdinPipe [PIPE_WRITE] pour fournir une entrée au processus enfant.
    • Lire les données d'un StdoutPipe[PIPE_READ] pour recevoir la sortie du processus enfant.

Implémentation

Le code C suivant illustre cette solution :

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>

using namespace std;

int main() {
  int aStdinPipe[2], aStdoutPipe[2];
  pid_t childPid;
  char buffer[1024];
  const char* command = "foo";
  string input = "Hello World!";

  // Create pipes
  if (pipe(aStdinPipe) == -1 || pipe(aStdoutPipe) == -1) {
    cerr << "Error creating pipes." << endl;
    return EXIT_FAILURE;
  }

  // Fork child process
  childPid = fork();
  if (childPid == -1) {
    cerr << "Error creating child process." << endl;
    return EXIT_FAILURE;
  }

  // Redirect IO in child process
  if (childPid == 0) {
    // Child process
    if (dup2(aStdinPipe[PIPE_READ], STDIN_FILENO) == -1 ||
        dup2(aStdoutPipe[PIPE_WRITE], STDOUT_FILENO) == -1 ||
        dup2(aStdoutPipe[PIPE_WRITE], STDERR_FILENO) == -1) {
      cerr << "Error redirecting IO in child." << endl;
      return EXIT_FAILURE;
    }

    // Close unused pipes
    close(aStdinPipe[PIPE_READ]);
    close(aStdinPipe[PIPE_WRITE]);
    close(aStdoutPipe[PIPE_WRITE]);

    // Execute command
    execve(command, NULL, NULL);
  }

  // Close unused pipes in parent process
  close(aStdinPipe[PIPE_READ]);
  close(aStdoutPipe[PIPE_WRITE]);

  // Write input to child process
  write(aStdinPipe[PIPE_WRITE], input.c_str(), input.length());

  // Read output from child process
  int numBytesRead = 0;
  while ((numBytesRead = read(aStdoutPipe[PIPE_READ], buffer, sizeof(buffer))) > 0) {
    cout.write(buffer, numBytesRead);
  }

  // Close remaining pipes
  close(aStdinPipe[PIPE_WRITE]);
  close(aStdoutPipe[PIPE_READ]);

  return EXIT_SUCCESS;
}

Ce code exécutera la commande foo avec la chaîne d'entrée input, et la sortie de foo sera imprimée sur la console .

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