GNU/Linux >> Linux Esercitazione >  >> Linux

Processo di creazione di Linux?

posix_spawn è probabilmente la soluzione preferita di questi tempi.

Prima di quel fork() e poi execXX() era il modo per farlo (dove execXX è uno dei exec famiglia di funzioni, incluso execl , execlp , execle , execv , execvp e execvpe ). Attualmente nella libreria GNU C, almeno per Linux, posix_spawn è implementato comunque tramite fork/exec; Linux non ha un posix_spawn chiamata di sistema.

Dovresti usare fork() (o vfork() ) per avviare un processo separato, che sarà un clone del genitore. Sia nel processo figlio che in quello padre, l'esecuzione continua, ma fork restituisce un valore diverso in entrambi i casi consentendo la differenziazione. Puoi quindi utilizzare uno dei execXX() funzioni dall'interno del processo figlio.

Nota, tuttavia, questo problema:testo preso in prestito da uno dei miei post sul blog (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):

Non sembra esserci alcun modo semplice conforme agli standard (o anche un modo generalmente portabile) per eseguire un altro processo in parallelo ed essere certi che la chiamata exec() abbia avuto successo. Il problema è che, una volta che hai fork()d e poi exec()d con successo, non puoi comunicare con il processo padre per informare che exec() ha avuto successo. Se exec() fallisce, puoi comunicare con il genitore (tramite un segnale per esempio) ma non puoi informare del successo - l'unico modo in cui il genitore può essere sicuro del successo di exec() è wait() per il figlio terminare il processo (e verificare che non ci siano indicazioni di errore) e che ovviamente non sia un'esecuzione parallela.

cioè se execXX() ha successo, non hai più il controllo quindi non puoi segnalare il successo al processo originale (genitore).

Una potenziale soluzione a questo problema, nel caso in cui sia un problema nel tuo caso:

utilizzare pipe() per creare una pipe, impostare l'estremità dell'output in modo che sia close-on-exec, quindi fork() (o vfork()), exec() e scrivere qualcosa (forse errno) nel pipe se exec() fallisce (prima di chiamare _exit()). Il processo genitore può leggere dalla pipe e otterrà un'immediata fine dell'input se exec() ha successo, o alcuni dati se exec() fallisce.

(Notare che questa soluzione attraverso è incline a causare l'inversione di priorità se il processo figlio viene eseguito con una priorità inferiore rispetto al genitore e il genitore attende l'output da esso).

C'è anche posix_spawn come menzionato sopra e in altre risposte, ma non risolve il problema del rilevamento della mancata esecuzione dell'eseguibile figlio, poiché è spesso implementato comunque in termini di fork/exec e può restituire il successo prima del exec() fase fallisce.


Il fork /exec combinazione è già stata citata, ma c'è anche il posix_spawn famiglia di funzioni che possono essere utilizzate in sostituzione di fork + exec ed è un equivalente più diretto di CreateProcess . Ecco un esempio per entrambe le possibilità:

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

Hai scritto:

Voglio creare un nuovo processo nella mia libreria senza sostituire l'attuale image.system() blocca il processo corrente, non va bene. Voglio continuare il processo in corso.

Basta aggiungere una e commerciale dopo la chiamata al comando. Esempio:system("/bin/my_prog_name &");

Il tuo processo non sarà bloccato!


Linux
  1. Come uccidere un processo zombie su Linux

  2. Linux:bloccare l'accesso alla rete di un processo?

  3. kill Esempi di comandi in Linux

  4. Creazione di un demone in Linux

  5. Linux:processo in un servizio

Come uccidere un processo in Linux

Comando Ps in Linux (Elenca processi)

Comando Pstree in Linux

Kill Command in Linux

Monitoraggio dei processi su Linux

Come KILL un processo su Linux