GNU/Linux >> Znalost Linux >  >> Linux

Linux CreateProcess?

posix_spawn je dnes pravděpodobně preferovaným řešením.

Před tím fork() a poté execXX() byl způsob, jak to udělat (kde execXX je jedním z exec rodina funkcí, včetně execl , execlp , execle , execv , execvp a execvpe ). V současné době v knihovně GNU C, alespoň pro Linux, posix_spawn je stejně implementován přes fork/exec; Linux nemá posix_spawn systémové volání.

Použili byste fork() (nebo vfork() ) ke spuštění samostatného procesu, který bude klonem rodiče. V podřízeném i nadřazeném procesu provádění pokračuje, ale fork v obou případech vrátí jinou hodnotu, což vám umožní rozlišovat. Poté můžete použít jeden z execXX() funkce z podřízeného procesu.

Všimněte si však tohoto problému – text vypůjčený z jednoho z mých blogových příspěvků (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):

Zdá se, že neexistuje žádný jednoduchý způsob, který by vyhovoval standardům (nebo dokonce obecně přenosný způsob), jak paralelně spustit jiný proces a mít jistotu, že volání exec() bylo úspěšné. Problém je v tom, že jakmile fork()d a poté úspěšně exec()d, nemůžete komunikovat s nadřazeným procesem, abyste informovali, že exec() bylo úspěšné. Pokud exec() selže, můžete komunikovat s rodičem (například prostřednictvím signálu), ale nemůžete informovat o úspěchu – jediný způsob, jak si rodič může být jistý úspěchem exec(), je počkat () na potomka. proces dokončit (a zkontrolovat, že neexistuje žádná indikace selhání) a že se samozřejmě nejedná o paralelní provádění.

tj. pokud execXX() uspěje, již nemáte kontrolu, takže nemůžete signalizovat úspěch původnímu (nadřazenému) procesu.

Potenciální řešení tohoto problému v případě, že se jedná o problém ve vašem případě:

[...] použijte pipe() k vytvoření roury, nastavte výstupní konec na close-on-exec, pak fork() (nebo vfork()), exec() a zapište něco (možná errno) do roura, pokud exec() selže (před voláním _exit()). Rodičovský proces může číst z roury a dostane okamžitý konec vstupu, pokud exec() uspěje, nebo nějaká data, pokud exec() selže.

(Všimněte si, že toto řešení může způsobit inverzi priority, pokud podřízený proces běží s nižší prioritou než nadřazený proces a rodič čeká na výstup z něj).

Existuje také posix_spawn jak je uvedeno výše a v jiných odpovědích, ale neřeší to problém detekce selhání při spuštění podřízeného spustitelného souboru, protože je často implementován z hlediska fork/exec a může vrátit úspěch před exec() fáze selže.


fork /exec kombinace již byla zmíněna, ale existuje také posix_spawn rodina funkcí, které lze použít jako náhradu za fork + exec a je přímějším ekvivalentem CreateProcess . Zde je příklad pro obě možnosti:

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

Napsal jsi:

Chci ve své knihovně vytvořit nový proces bez nahrazení aktuálního spouštění image.system() blokuje aktuální proces, není to dobré. Chci pokračovat v aktuálním procesu.

Stačí za příkaz call přidat ampersand. Příklad:system("/bin/my_prog_name &");

Váš proces nebude zablokován!


Linux
  1. Linux – Blokovat síťový přístup procesu?

  2. Linux – proces „subreaper“?

  3. Příklady příkazů kill v Linuxu

  1. Vytvoření démona v Linuxu

  2. Linux:proces do služby

  3. Může být proces init shell skript v Linuxu?

  1. Jak zabít proces zombie na Linuxu

  2. Jak nainstalovat vtop na Linux

  3. Úvod do Linuxových vláken – část I