GNU/Linux >> Tutoriels Linux >  >> Linux

Créer un processus Linux ?

posix_spawn est probablement la solution préférée de nos jours.

Avant cela fork() puis execXX() était le moyen de le faire (où execXX fait partie des exec famille de fonctions, dont execl , execlp , execle , execv , execvp , et execvpe ). Dans la bibliothèque GNU C actuellement, au moins pour Linux, posix_spawn est de toute façon implémenté via fork/exec ; Linux n'a pas de posix_spawn appel système.

Vous utiliseriez fork() (ou vfork() ) pour lancer un processus séparé, qui sera un clone du parent. Dans le processus enfant et parent, l'exécution continue, mais fork renvoie une valeur différente dans les deux cas, ce qui vous permet de différencier. Vous pouvez alors utiliser l'un des execXX() fonctions à partir du processus enfant.

Notez cependant ce problème - texte emprunté à l'un de mes articles de blog (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):

Il ne semble pas y avoir de moyen simple conforme aux normes (ou même de moyen généralement portable) pour exécuter un autre processus en parallèle et être certain que l'appel exec() a réussi. Le problème est qu'une fois que vous avez fork () puis exécuté avec succès, vous ne pouvez pas communiquer avec le processus parent pour informer que l'exec () a réussi. Si exec() échoue, vous pouvez communiquer avec le parent (via un signal par exemple) mais vous ne pouvez pas informer du succès - la seule façon pour le parent d'être sûr du succès de exec() est d'attendre() pour l'enfant processus à terminer (et vérifiez qu'il n'y a pas d'indication d'échec) et qu'il ne s'agit bien sûr pas d'une exécution parallèle.

c'est-à-dire si execXX() réussit, vous n'avez plus le contrôle et ne pouvez donc pas signaler le succès au processus d'origine (parent).

Une solution potentielle à ce problème, au cas où il s'agirait d'un problème dans votre cas :

[...] utilisez pipe() pour créer un tube, définissez la fin de la sortie sur close-on-exec, puis fork() (ou vfork()), exec() et écrivez quelque chose (peut-être errno) dans le pipe si exec() échoue (avant d'appeler _exit()). Le processus parent peut lire à partir du tube et obtiendra une fin d'entrée immédiate si exec() réussit, ou des données si exec() échoue.

(Notez que cette solution est susceptible de provoquer une inversion de priorité si le processus enfant s'exécute avec une priorité inférieure à celle du parent et que le parent attend sa sortie).

Il y a aussi posix_spawn comme mentionné ci-dessus et dans d'autres réponses, mais cela ne résout pas le problème de la détection de l'échec de l'exécution de l'exécutable enfant, car il est souvent implémenté en termes de fork/exec de toute façon et peut renvoyer le succès avant le exec() l'étape échoue.


Le fork /exec la combinaison a déjà été mentionnée, mais il y a aussi le posix_spawn famille de fonctions pouvant remplacer fork + exec et est un équivalent plus direct de CreateProcess . Voici un exemple pour les deux possibilités :

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <unistd.h>
#include <spawn.h>
#include <sys/wait.h>

extern char **environ;

void test_fork_exec(void);
void test_posix_spawn(void);

int main(void) {
  test_fork_exec();
  test_posix_spawn();
  return EXIT_SUCCESS;
}

void test_fork_exec(void) {
  pid_t pid;
  int status;
  puts("Testing fork/exec");
  fflush(NULL);
  pid = fork();
  switch (pid) {
  case -1:
    perror("fork");
    break;
  case 0:
    execl("/bin/ls", "ls", (char *) 0);
    perror("exec");
    break;
  default:
    printf("Child id: %i\n", pid);
    fflush(NULL);
    if (waitpid(pid, &status, 0) != -1) {
      printf("Child exited with status %i\n", status);
    } else {
      perror("waitpid");
    }
    break;
  }
}

void test_posix_spawn(void) {
  pid_t pid;
  char *argv[] = {"ls", (char *) 0};
  int status;
  puts("Testing posix_spawn");
  fflush(NULL);
  status = posix_spawn(&pid, "/bin/ls", NULL, NULL, argv, environ);
  if (status == 0) {
    printf("Child id: %i\n", pid);
    fflush(NULL);
    if (waitpid(pid, &status, 0) != -1) {
      printf("Child exited with status %i\n", status);
    } else {
      perror("waitpid");
    }
  } else {
    printf("posix_spawn: %s\n", strerror(status));
  }
}

Vous avez écrit :

Je veux créer un nouveau processus dans ma bibliothèque sans remplacer l'image en cours d'exécution. system() bloque le processus en cours, ce n'est pas bon. Je veux continuer le processus en cours.

Ajoutez simplement une esperluette après l'appel de la commande.Exemple :system("/bin/my_prog_name &");

Votre processus ne sera pas bloqué !


Linux
  1. Comment installer vtop sur Linux

  2. Processus de démarrage Linux

  3. Options de commande nohup sous Linux

  4. Exemples de commandes renice sous Linux

  5. Linux :transformer en service

Comment tuer un processus sous Linux

Commande Ps sous Linux (liste des processus)

Commande Pstree sous Linux

Commande Kill sous Linux

Surveillance des processus sous Linux

Comment tuer un processus sous Linux