GNU/Linux >> Tutoriales Linux >  >> Linux

¿Linux CreateProcess?

posix_spawn es probablemente la solución preferida en estos días.

Antes de eso fork() y luego execXX() era la manera de hacer esto (donde execXX es uno de los exec familia de funciones, incluyendo execl , execlp , execle , execv , execvp y execvpe ). En la biblioteca GNU C actualmente, al menos para Linux, posix_spawn se implementa a través de fork/exec de todos modos; Linux no tiene un posix_spawn llamada al sistema.

Usarías fork() (o vfork() ) para iniciar un proceso separado, que será un clon del padre. Tanto en el proceso hijo como en el padre, la ejecución continúa, pero fork devuelve un valor diferente en cualquier caso, lo que le permite diferenciar. A continuación, puede utilizar uno de los execXX() funciones desde dentro del proceso hijo.

Tenga en cuenta, sin embargo, este problema:texto tomado de una de mis publicaciones de blog (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):

No parece haber ninguna forma simple que cumpla con los estándares (o incluso una forma portátil en general) para ejecutar otro proceso en paralelo y estar seguro de que la llamada exec() fue exitosa. El problema es que, una vez que haya bifurcado() y luego ejecutado con éxito, no puede comunicarse con el proceso principal para informar que el exec() fue exitoso. Si el exec () falla, entonces puede comunicarse con el padre (a través de una señal, por ejemplo) pero no puede informar el éxito; la única forma en que el padre puede estar seguro del éxito del exec () es esperar () para el niño finalice el proceso (y verifique que no haya indicación de falla) y que por supuesto no sea una ejecución paralela.

es decir, si execXX() tiene éxito, ya no tiene el control, por lo que no puede señalar el éxito del proceso original (principal).

Una posible solución a este problema, en caso de que sea un problema en su caso:

[...] use pipe() para crear una tubería, configure el extremo de salida para que sea close-on-exec, luego fork() (o vfork()), exec(), y escriba algo (quizás errno) en el tubería si el exec() falla (antes de llamar a _exit()). El proceso principal puede leer de la canalización y obtendrá un final de entrada inmediato si exec() tiene éxito, o algunos datos si exec() falla.

(Tenga en cuenta que esta solución es propensa a causar una inversión de prioridad si el proceso secundario se ejecuta con una prioridad más baja que el principal y el principal espera el resultado).

También hay posix_spawn como se mencionó anteriormente y en otras respuestas, pero no resuelve el problema de detectar fallas al ejecutar el ejecutable secundario, ya que a menudo se implementa en términos de fork/exec de todos modos y puede devolver el éxito antes del exec() la etapa falla.


El fork /exec Ya se mencionó la combinación, pero también existe el posix_spawn familia de funciones que se pueden usar como reemplazo de fork + exec y es un equivalente más directo a CreateProcess . Aquí hay un ejemplo para ambas posibilidades:

#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));
  }
}

Tú escribiste:

Quiero crear un nuevo proceso en mi biblioteca sin reemplazar la imagen en ejecución actual. system() bloquea el proceso actual, no es bueno. Quiero continuar con el proceso actual.

Simplemente agregue un ampersand después de la llamada de comando. Ejemplo:system("/bin/my_prog_name &");

¡Su proceso no será bloqueado!


Linux
  1. Introducción a los subprocesos de Linux - Parte I

  2. Proceso de arranque de Linux

  3. Ejemplos de comandos kill en Linux

  4. Ejemplos de comandos renice en Linux

  5. Crear un demonio en Linux

Cómo matar un proceso en Linux

Comando Ps en Linux (Lista de Procesos)

Comando Pstree en Linux

Comando matar en Linux

Supervisión de procesos en Linux

Cómo MATAR un proceso en Linux