02
ist heutzutage wahrscheinlich die bevorzugte Lösung.
Davor 16
und dann 25
war der Weg, dies zu tun (wobei 33
ist einer der 45
Funktionsfamilie, einschließlich 57
, 64
, 74
, 82
, 99
, und 104
). In der GNU C-Bibliothek derzeit, zumindest für Linux, 118
wird sowieso über fork/exec implementiert; Linux hat keinen 121
Systemaufruf.
Sie würden 134
verwenden (oder 140
), um einen separaten Prozess zu starten, der ein Klon des übergeordneten Prozesses sein wird. Sowohl im untergeordneten als auch im übergeordneten Prozess wird die Ausführung fortgesetzt, aber 153
gibt in beiden Fällen einen anderen Wert zurück, sodass Sie unterscheiden können. Sie können dann einen der 161
verwenden Funktionen innerhalb des untergeordneten Prozesses.
Beachten Sie jedoch dieses Problem - Text aus einem meiner Blog-Einträge (http://davmac.wordpress.com/2008/11/25/forkexec-is-forked-up/):
Es scheint keine einfache standardkonforme (oder überhaupt tragbare) Möglichkeit zu geben, einen anderen Prozess parallel auszuführen und sicher zu sein, dass der Aufruf von exec() erfolgreich war. Das Problem ist, sobald Sie fork()d und dann erfolgreich exec()d ausgeführt haben, können Sie nicht mit dem übergeordneten Prozess kommunizieren, um ihn darüber zu informieren, dass exec() erfolgreich war. Wenn exec() fehlschlägt, können Sie mit dem Elternteil kommunizieren (zum Beispiel über ein Signal), aber Sie können ihn nicht über den Erfolg informieren – der einzige Weg, wie der Elternteil sicher sein kann, dass exec() erfolgreich ist, besteht darin, auf das Kind zu warten() Prozess zu beenden (und überprüfen Sie, dass es keine Fehleranzeige gibt) und dass es sich natürlich nicht um eine parallele Ausführung handelt.
d.h. wenn 172
erfolgreich ist, haben Sie keine Kontrolle mehr und können dem ursprünglichen (übergeordneten) Prozess keinen Erfolg signalisieren.
Eine mögliche Lösung für dieses Problem, falls es in Ihrem Fall ein Problem ist:
[...] verwenden Sie pipe(), um eine Pipe zu erstellen, setzen Sie das Ausgabeende auf close-on-exec, dann fork() (oder vfork()), exec() und schreiben Sie etwas (vielleicht errno) in die Pipe, wenn exec() fehlschlägt (vor dem Aufruf von _exit()). Der übergeordnete Prozess kann aus der Pipe lesen und erhält ein sofortiges Ende der Eingabe, wenn exec() erfolgreich ist, oder einige Daten, wenn exec() fehlschlägt.
(Beachten Sie, dass diese Lösung dazu neigt, eine Prioritätsumkehr zu verursachen, wenn der untergeordnete Prozess mit einer niedrigeren Priorität als der übergeordnete Prozess ausgeführt wird und der übergeordnete Prozess auf die Ausgabe von ihm wartet).
Es gibt auch 186
wie oben und in anderen Antworten erwähnt, aber es löst nicht das Problem der Erkennung von Fehlern bei der Ausführung der untergeordneten ausführbaren Datei, da sie häufig ohnehin in Bezug auf Fork/Exec implementiert wird und vor dem 194
Phase schlägt fehl.
Die 204
/213
Kombination wurde bereits erwähnt, aber es gibt auch die 226
Familie von Funktionen, die als Ersatz für 235
verwendet werden können + 240
und ist ein direkteres Äquivalent zu 254
. Hier ein Beispiel für beide Möglichkeiten:
#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));
}
}
Du hast geschrieben:
Ich möchte einen neuen Prozess in meiner Bibliothek erstellen, ohne das aktuell ausgeführte image.system() zu ersetzen, blockiert den aktuellen Prozess, es ist nicht gut. Ich möchte den aktuellen Prozess fortsetzen.
Fügen Sie nach dem Befehlsaufruf einfach ein kaufmännisches Und hinzu. Beispiel:269
Ihr Prozess wird nicht blockiert!