@Justin, weil wir wollen , SO werden der Platz für die Programmierung Fragen zu gehen.
Paxdiablo
4
@ Polaris878: oh, das tut es jetzt! : D
Janusz Lenar
so forkist im Grunde Klonen: O
Sebastian Hojas
Antworten:
363
Die Verwendung forkund execVeranschaulichung des Geistes von UNIX bietet eine sehr einfache Möglichkeit, neue Prozesse zu starten.
Der forkAufruf erstellt im Grunde genommen ein Duplikat des aktuellen Prozesses, das in fast jeder Hinsicht identisch ist . Es wird nicht alles kopiert (z. B. Ressourcenbeschränkungen in einigen Implementierungen), aber die Idee ist, eine möglichst enge Kopie zu erstellen.
Der neue Prozess (untergeordnet) erhält eine andere Prozess-ID (PID) und hat die PID des alten Prozesses (übergeordnet) als übergeordnete PID (PPID). Da die beiden Prozesse jetzt genau denselben Code ausführen, können sie anhand des Rückkehrcodes von fork- das Kind erhält 0, das Elternteil erhält die PID des Kindes - erkennen, welcher Code welcher ist . Dies alles ist natürlich vorausgesetzt, dass der forkAufruf funktioniert. Wenn nicht, wird kein untergeordnetes Element erstellt und das übergeordnete Element erhält einen Fehlercode.
Der execAufruf ist eine Möglichkeit, den gesamten aktuellen Prozess durch ein neues Programm zu ersetzen. Es lädt das Programm in den aktuellen Prozessbereich und führt es vom Einstiegspunkt aus.
So, forkund execwerden oft in Folge als Kind eines aktuellen Prozesses ausgeführt wird, ein neues Programm zu bekommen. Shells tun dies normalerweise immer dann, wenn Sie versuchen, ein Programm wie find- die Shell-Gabeln - auszuführen. Dann lädt das Kind das findProgramm in den Speicher und richtet alle Befehlszeilenargumente, Standard-E / A usw. ein.
Sie müssen jedoch nicht zusammen verwendet werden. Es ist für ein Programm für sich forkselbst völlig akzeptabel, execwenn das Programm beispielsweise sowohl übergeordneten als auch untergeordneten Code enthält (Sie müssen vorsichtig sein, was Sie tun, jede Implementierung kann Einschränkungen aufweisen). Dies wurde (und wird immer noch) häufig für Dämonen verwendet, die einfach einen TCP-Port und forkeine Kopie von sich selbst abhören , um eine bestimmte Anforderung zu verarbeiten, während die Eltern wieder zuhören.
In ähnlichen Programme , die sie sind fertig wissen und wollen einfach nur ein anderes Programm nicht laufen müssen fork, execund dann waitfür das Kind. Sie können das Kind einfach direkt in ihren Prozessraum laden.
Einige UNIX-Implementierungen sind optimiert forkund verwenden das, was sie Copy-on-Write nennen. Dies ist ein Trick, um das Kopieren des Prozessbereichs zu verzögern, forkbis das Programm versucht, etwas in diesem Bereich zu ändern. Dies ist nützlich für Programme, die nur verwenden forkund nicht exec, da sie nicht den gesamten Prozessbereich kopieren müssen.
Wenn das execwird genannt folgende fork(und das ist , was meist geschieht), führt dazu , dass ein Schreiben in den Prozessraum und es wird dann für das Kind Prozess kopiert.
Beachten Sie, dass es eine ganze Familie von ist execGespräche ( execl, execle, execveund so weiter) , aber execin Zusammenhang bedeutet hier eine von ihnen.
Das folgende Diagramm zeigt die typische fork/execOperation, bei der die bashShell zum Auflisten eines Verzeichnisses mit dem lsBefehl verwendet wird:
+--------+| pid=7|| ppid=4|| bash |+--------+|| calls fork
V
+--------++--------+| pid=7| forks | pid=22|| ppid=4|---------->| ppid=7|| bash || bash |+--------++--------+||| waits for pid 22| calls exec to run ls
| V
|+--------+|| pid=22||| ppid=7||| ls |
V +--------++--------+|| pid=7|| exits
| ppid=4|<---------------+| bash |+--------+|| continues
V
fork()teilt den aktuellen Prozess in zwei Prozesse auf. Mit anderen Worten, Ihr schönes lineares, leicht zu denkendes Programm wird plötzlich zu zwei separaten Programmen, auf denen ein Code ausgeführt wird:
int pid = fork();if(pid ==0){
printf("I'm the child");}else{
printf("I'm the parent, my child is %i", pid);// here we can kill the child, but that's not very parently of us}
Dies kann Sie umhauen. Jetzt haben Sie einen Code mit einem ziemlich identischen Status, der von zwei Prozessen ausgeführt wird. Der untergeordnete Prozess erbt den gesamten Code und den Speicher des Prozesses, der ihn gerade erstellt hat, einschließlich der Stelle, an der der fork()Anruf gerade aufgehört hat. Der einzige Unterschied ist der fork()Rückkehrcode, der Ihnen sagt, ob Sie der Elternteil oder das Kind sind. Wenn Sie der Elternteil sind, ist der Rückgabewert die ID des Kindes.
execist etwas einfacher zu verstehen, Sie müssen nur execeinen Prozess mit der ausführbaren Zieldatei ausführen, und Sie haben nicht zwei Prozesse, die denselben Code ausführen oder denselben Status erben. Wie @Steve Hawkins sagt, execkann verwendet werden, nachdem Sie forkim aktuellen Prozess die ausführbare Zieldatei ausgeführt haben.
Es gibt auch die Bedingung, wann pid < 0und der fork()Anruf fehlgeschlagen ist
Jonathan Fingland
3
Das macht mich überhaupt nicht fertig :-) Jedes Mal, wenn eine gemeinsam genutzte Bibliothek oder DLL verwendet wird, wird ein Code ausgeführt, der von zwei Prozessen ausgeführt wird.
Paxdiablo
31
Ich denke, einige Konzepte aus "Advanced Unix Programming" von Marc Rochkind waren hilfreich, um die verschiedenen Rollen von fork()/ zu verstehen exec(), insbesondere für jemanden, der an das Windows- CreateProcess()Modell gewöhnt ist :
Ein Programm ist eine Sammlung von Anweisungen und Daten, die in einer regulären Datei auf der Festplatte gespeichert sind. (ab 1.1.2 Programme, Prozesse und Threads)
.
Um ein Programm auszuführen, wird der Kernel zunächst aufgefordert, einen neuen Prozess zu erstellen. Dies ist eine Umgebung, in der ein Programm ausgeführt wird. (auch ab 1.1.2 Programme, Prozesse und Threads)
.
Es ist unmöglich, die Systemaufrufe exec oder fork zu verstehen, ohne die Unterscheidung zwischen einem Prozess und einem Programm vollständig zu verstehen. Wenn diese Begriffe für Sie neu sind, können Sie zurückgehen und Abschnitt 1.1.2 lesen. Wenn Sie jetzt fortfahren können, fassen wir die Unterscheidung in einem Satz zusammen: Ein Prozess ist eine Ausführungsumgebung, die aus Anweisungs-, Benutzerdaten- und Systemdatensegmenten sowie vielen anderen zur Laufzeit erworbenen Ressourcen besteht Während ein Programm eine Datei ist, die Anweisungen und Daten enthält, die zum Initialisieren der Anweisungs- und Benutzerdatensegmente eines Prozesses verwendet werden. (ab 5.3 execSystemaufrufe)
Sobald Sie die Unterscheidung zwischen einem Programm und einem Prozess verstanden haben, können Sie das Verhalten fork()und die exec()Funktion wie folgt zusammenfassen:
fork() Erstellt ein Duplikat des aktuellen Prozesses
exec() Ersetzt das Programm im aktuellen Prozess durch ein anderes Programm
Fork erstellt eine Kopie eines aufrufenden Prozesses. folgt im Allgemeinen der Struktur
int cpid = fork();if(cpid ==0){//child code
exit(0);}//parent code
wait(cpid);// end
(Für untergeordneten Prozesstext (Code), Daten entspricht der Stapel dem aufrufenden Prozess.) Der untergeordnete Prozess führt Code im if-Block aus.
EXEC ersetzt den aktuellen Prozess durch den Code, die Daten und den Stapel des neuen Prozesses. folgt im Allgemeinen der Struktur
int cpid = fork();if(cpid ==0){//child code
exec(foo);
exit(0);}//parent code
wait(cpid);// end
(Nach dem Exec-Aufruf löscht der Unix-Kernel den Text, die Daten, den Stapel des untergeordneten Prozesses und füllt ihn mit foo-prozessbezogenen Texten / Daten.) Der untergeordnete Prozess hat also einen anderen Code (foo-Code {nicht identisch mit übergeordnetem Code}).
Es hat nichts mit der Frage zu tun, aber verursacht dieser Code oben keine Race-Bedingung, wenn der untergeordnete Prozess seinen Code zuerst beendet? In diesem Fall würde der Elternprozess für immer herumhängen und darauf warten, dass das Kind sich selbst beendet, oder?
Stdout
7
Sie werden zusammen verwendet, um einen neuen untergeordneten Prozess zu erstellen. Beim Erstellen forkwird zunächst eine Kopie des aktuellen Prozesses (des untergeordneten Prozesses) erstellt. Wird execdann aus dem untergeordneten Prozess heraus aufgerufen, um die Kopie des übergeordneten Prozesses durch den neuen Prozess zu "ersetzen".
Der Prozess läuft ungefähr so ab:
child = fork();//Fork returns a PID for the parent process, or 0 for the child, or -1 for Failif(child <0){
std::cout <<"Failed to fork GUI process...Exiting"<< std::endl;
exit (-1);}elseif(child ==0){// This is the Child Process// Call one of the "exec" functions to create the child process
execvp (argv[0],const_cast<char**>(argv));}else{// This is the Parent Process//Continue executing parent process}
In der siebten Zeile wird erwähnt, dass die Funktion exec () den untergeordneten Prozess erstellt. Ist dies wirklich der Fall, weil fork () den
untergeordneten
4
fork () erstellt eine Kopie des aktuellen Prozesses, wobei die Ausführung im neuen untergeordneten Element unmittelbar nach dem Aufruf von fork () beginnt. Nach fork () sind sie bis auf den Rückgabewert der Funktion fork () identisch. (RTFM für weitere Details.) Die beiden Prozesse können dann noch weiter voneinander abweichen, wobei einer den anderen nicht stören kann, außer möglicherweise über gemeinsam genutzte Dateihandles.
exec () ersetzt den aktuellen Prozess durch einen neuen. Es hat nichts mit fork () zu tun, außer dass exec () häufig auf fork () folgt, wenn ein anderer untergeordneter Prozess gestartet werden soll, anstatt den aktuellen zu ersetzen.
Der Hauptunterschied zwischen fork()und exec()ist, dass
Der fork()Systemaufruf erstellt einen Klon des aktuell ausgeführten Programms. Das ursprüngliche Programm setzt die Ausführung mit der nächsten Codezeile nach dem Funktionsaufruf fork () fort. Der Klon startet auch die Ausführung in der nächsten Codezeile. Schauen Sie sich den folgenden Code an, den ich von http://timmurphy.org/2014/04/26/using-fork-in-cc-a-minimum-working-example/ erhalten habe.
#include<stdio.h>#include<unistd.h>int main(int argc,char**argv){
printf("--beginning of program\n");int counter =0;pid_t pid = fork();if(pid ==0){// child processint i =0;for(; i <5;++i){
printf("child process: counter=%d\n",++counter);}}elseif(pid >0){// parent processint j =0;for(; j <5;++j){
printf("parent process: counter=%d\n",++counter);}}else{// fork failed
printf("fork() failed!\n");return1;}
printf("--end of program--\n");return0;}
Dieses Programm deklariert eine auf Null gesetzte Zählervariable, bevor fork()ing. Nach dem Fork-Aufruf werden zwei Prozesse parallel ausgeführt, wobei beide ihre eigene Version des Zählers erhöhen. Jeder Prozess wird vollständig ausgeführt und beendet. Da die Prozesse parallel ablaufen, können wir nicht wissen, welche zuerst abgeschlossen werden. Wenn Sie dieses Programm ausführen, wird etwas Ähnliches wie das unten gezeigte gedruckt, obwohl die Ergebnisse von Lauf zu Lauf variieren können.
--beginning of program
parent process: counter=1
parent process: counter=2
parent process: counter=3
child process: counter=1
parent process: counter=4
child process: counter=2
parent process: counter=5
child process: counter=3--end of program--
child process: counter=4
child process: counter=5--end of program--
Die exec()Familie der Systemaufrufe ersetzt den aktuell ausgeführten Code eines Prozesses durch einen anderen Code. Der Prozess behält seine PID bei, wird jedoch zu einem neuen Programm. Betrachten Sie beispielsweise den folgenden Code:
#include<stdio.h>#include<unistd.h>
main(){char program[80],*args[3];int i;
printf("Ready to exec()...\n");
strcpy(program,"date");
args[0]="date";
args[1]="-u";
args[2]=NULL;
i=execvp(program,args);
printf("i=%d ... did it work?\n",i);}
Dieses Programm ruft die execvp()Funktion auf, um ihren Code durch das Datumsprogramm zu ersetzen. Wenn der Code in einer Datei mit dem Namen exec1.c gespeichert ist, führt die Ausführung zu der folgenden Ausgabe:
Ready to exec()...TueJul1520:17:53 UTC 2008
Das Programm gibt die Zeile ―Ready to exec () aus. . . ‖ Ersetzt nach dem Aufruf der Funktion execvp () den Code durch das Datumsprogramm. Beachten Sie, dass die Zeile -. . . hat es funktioniert‖ wird nicht angezeigt, da zu diesem Zeitpunkt der Code ersetzt wurde. Stattdessen sehen wir die Ausgabe der Ausführung von "Datum -u".
Es wird eine Kopie des laufenden Prozesses erstellt. Der laufende Prozess wird als übergeordneter Prozess und der neu erstellte Prozess als untergeordneter Prozess bezeichnet . Die Art und Weise, die beiden zu unterscheiden, besteht darin, den zurückgegebenen Wert zu betrachten:
fork() Gibt die Prozesskennung (pid) des untergeordneten Prozesses im übergeordneten Prozess zurück
fork() gibt im Kind 0 zurück.
exec()::
Es initiiert einen neuen Prozess innerhalb eines Prozesses. Es lädt ein neues Programm in den aktuellen Prozess und ersetzt das vorhandene.
fork()+ exec():
Wenn Sie ein neues Programm starten, müssen Sie zunächst fork()einen neuen Prozess erstellen und dann exec()(dh in den Speicher laden und ausführen) die Programmbinärdatei ausführen, die ausgeführt werden soll.
int main(void){int pid = fork();if( pid ==0){
execvp("find", argv );}//Put the parent to sleep for 2 sec,let the child finished executing
wait(2);return0;}
Das beste Beispiel zu verstehen , das fork()und exec()Konzept ist die Schale , Programm die Befehlsinterpreter , dass Benutzer führen typischerweise nach der Protokollierung in dem Shell interpretiert System das erste Wort der Kommandozeile als Befehlsnamen
Bei vielen Befehlen führen die Shell- Gabeln und der untergeordnete Prozess den dem Namen zugeordneten Befehl aus, wobei die verbleibenden Wörter in der Befehlszeile als Parameter für den Befehl behandelt werden.
Die Shell erlaubt drei Arten von Befehlen. Erstens kann ein Befehl eine
ausführbare Datei sein , die Objektcode enthält, der durch Kompilieren des Quellcodes erzeugt wird (z. B. ein C-Programm). Zweitens kann ein Befehl eine ausführbare Datei sein, die eine Folge von Shell-Befehlszeilen enthält. Schließlich kann ein Befehl ein interner Shell-Befehl sein (anstelle einer ausführbaren Datei ex-> cd , ls usw.).
fork
ist im Grunde Klonen: OAntworten:
Die Verwendung
fork
undexec
Veranschaulichung des Geistes von UNIX bietet eine sehr einfache Möglichkeit, neue Prozesse zu starten.Der
fork
Aufruf erstellt im Grunde genommen ein Duplikat des aktuellen Prozesses, das in fast jeder Hinsicht identisch ist . Es wird nicht alles kopiert (z. B. Ressourcenbeschränkungen in einigen Implementierungen), aber die Idee ist, eine möglichst enge Kopie zu erstellen.Der neue Prozess (untergeordnet) erhält eine andere Prozess-ID (PID) und hat die PID des alten Prozesses (übergeordnet) als übergeordnete PID (PPID). Da die beiden Prozesse jetzt genau denselben Code ausführen, können sie anhand des Rückkehrcodes von
fork
- das Kind erhält 0, das Elternteil erhält die PID des Kindes - erkennen, welcher Code welcher ist . Dies alles ist natürlich vorausgesetzt, dass derfork
Aufruf funktioniert. Wenn nicht, wird kein untergeordnetes Element erstellt und das übergeordnete Element erhält einen Fehlercode.Der
exec
Aufruf ist eine Möglichkeit, den gesamten aktuellen Prozess durch ein neues Programm zu ersetzen. Es lädt das Programm in den aktuellen Prozessbereich und führt es vom Einstiegspunkt aus.So,
fork
undexec
werden oft in Folge als Kind eines aktuellen Prozesses ausgeführt wird, ein neues Programm zu bekommen. Shells tun dies normalerweise immer dann, wenn Sie versuchen, ein Programm wiefind
- die Shell-Gabeln - auszuführen. Dann lädt das Kind dasfind
Programm in den Speicher und richtet alle Befehlszeilenargumente, Standard-E / A usw. ein.Sie müssen jedoch nicht zusammen verwendet werden. Es ist für ein Programm für sich
fork
selbst völlig akzeptabel,exec
wenn das Programm beispielsweise sowohl übergeordneten als auch untergeordneten Code enthält (Sie müssen vorsichtig sein, was Sie tun, jede Implementierung kann Einschränkungen aufweisen). Dies wurde (und wird immer noch) häufig für Dämonen verwendet, die einfach einen TCP-Port undfork
eine Kopie von sich selbst abhören , um eine bestimmte Anforderung zu verarbeiten, während die Eltern wieder zuhören.In ähnlichen Programme , die sie sind fertig wissen und wollen einfach nur ein anderes Programm nicht laufen müssen
fork
,exec
und dannwait
für das Kind. Sie können das Kind einfach direkt in ihren Prozessraum laden.Einige UNIX-Implementierungen sind optimiert
fork
und verwenden das, was sie Copy-on-Write nennen. Dies ist ein Trick, um das Kopieren des Prozessbereichs zu verzögern,fork
bis das Programm versucht, etwas in diesem Bereich zu ändern. Dies ist nützlich für Programme, die nur verwendenfork
und nichtexec
, da sie nicht den gesamten Prozessbereich kopieren müssen.Wenn das
exec
wird genannt folgendefork
(und das ist , was meist geschieht), führt dazu , dass ein Schreiben in den Prozessraum und es wird dann für das Kind Prozess kopiert.Beachten Sie, dass es eine ganze Familie von ist
exec
Gespräche (execl
,execle
,execve
und so weiter) , aberexec
in Zusammenhang bedeutet hier eine von ihnen.Das folgende Diagramm zeigt die typische
fork/exec
Operation, bei der diebash
Shell zum Auflisten eines Verzeichnisses mit demls
Befehl verwendet wird:quelle
fork()
teilt den aktuellen Prozess in zwei Prozesse auf. Mit anderen Worten, Ihr schönes lineares, leicht zu denkendes Programm wird plötzlich zu zwei separaten Programmen, auf denen ein Code ausgeführt wird:Dies kann Sie umhauen. Jetzt haben Sie einen Code mit einem ziemlich identischen Status, der von zwei Prozessen ausgeführt wird. Der untergeordnete Prozess erbt den gesamten Code und den Speicher des Prozesses, der ihn gerade erstellt hat, einschließlich der Stelle, an der der
fork()
Anruf gerade aufgehört hat. Der einzige Unterschied ist derfork()
Rückkehrcode, der Ihnen sagt, ob Sie der Elternteil oder das Kind sind. Wenn Sie der Elternteil sind, ist der Rückgabewert die ID des Kindes.exec
ist etwas einfacher zu verstehen, Sie müssen nurexec
einen Prozess mit der ausführbaren Zieldatei ausführen, und Sie haben nicht zwei Prozesse, die denselben Code ausführen oder denselben Status erben. Wie @Steve Hawkins sagt,exec
kann verwendet werden, nachdem Siefork
im aktuellen Prozess die ausführbare Zieldatei ausgeführt haben.quelle
pid < 0
und derfork()
Anruf fehlgeschlagen istIch denke, einige Konzepte aus "Advanced Unix Programming" von Marc Rochkind waren hilfreich, um die verschiedenen Rollen von
fork()
/ zu verstehenexec()
, insbesondere für jemanden, der an das Windows-CreateProcess()
Modell gewöhnt ist :.
.
Sobald Sie die Unterscheidung zwischen einem Programm und einem Prozess verstanden haben, können Sie das Verhalten
fork()
und dieexec()
Funktion wie folgt zusammenfassen:fork()
Erstellt ein Duplikat des aktuellen Prozessesexec()
Ersetzt das Programm im aktuellen Prozess durch ein anderes Programm(Dies ist im Wesentlichen eine vereinfachte 'für Dummies'- Version von Paxdiablos viel detaillierterer Antwort )
quelle
Fork erstellt eine Kopie eines aufrufenden Prozesses. folgt im Allgemeinen der Struktur
(Für untergeordneten Prozesstext (Code), Daten entspricht der Stapel dem aufrufenden Prozess.) Der untergeordnete Prozess führt Code im if-Block aus.
EXEC ersetzt den aktuellen Prozess durch den Code, die Daten und den Stapel des neuen Prozesses. folgt im Allgemeinen der Struktur
(Nach dem Exec-Aufruf löscht der Unix-Kernel den Text, die Daten, den Stapel des untergeordneten Prozesses und füllt ihn mit foo-prozessbezogenen Texten / Daten.) Der untergeordnete Prozess hat also einen anderen Code (foo-Code {nicht identisch mit übergeordnetem Code}).
quelle
Sie werden zusammen verwendet, um einen neuen untergeordneten Prozess zu erstellen. Beim Erstellen
fork
wird zunächst eine Kopie des aktuellen Prozesses (des untergeordneten Prozesses) erstellt. Wirdexec
dann aus dem untergeordneten Prozess heraus aufgerufen, um die Kopie des übergeordneten Prozesses durch den neuen Prozess zu "ersetzen".Der Prozess läuft ungefähr so ab:
quelle
fork () erstellt eine Kopie des aktuellen Prozesses, wobei die Ausführung im neuen untergeordneten Element unmittelbar nach dem Aufruf von fork () beginnt. Nach fork () sind sie bis auf den Rückgabewert der Funktion fork () identisch. (RTFM für weitere Details.) Die beiden Prozesse können dann noch weiter voneinander abweichen, wobei einer den anderen nicht stören kann, außer möglicherweise über gemeinsam genutzte Dateihandles.
exec () ersetzt den aktuellen Prozess durch einen neuen. Es hat nichts mit fork () zu tun, außer dass exec () häufig auf fork () folgt, wenn ein anderer untergeordneter Prozess gestartet werden soll, anstatt den aktuellen zu ersetzen.
quelle
Der Hauptunterschied zwischen
fork()
undexec()
ist, dassDer
fork()
Systemaufruf erstellt einen Klon des aktuell ausgeführten Programms. Das ursprüngliche Programm setzt die Ausführung mit der nächsten Codezeile nach dem Funktionsaufruf fork () fort. Der Klon startet auch die Ausführung in der nächsten Codezeile. Schauen Sie sich den folgenden Code an, den ich von http://timmurphy.org/2014/04/26/using-fork-in-cc-a-minimum-working-example/ erhalten habe.Dieses Programm deklariert eine auf Null gesetzte Zählervariable, bevor
fork()
ing. Nach dem Fork-Aufruf werden zwei Prozesse parallel ausgeführt, wobei beide ihre eigene Version des Zählers erhöhen. Jeder Prozess wird vollständig ausgeführt und beendet. Da die Prozesse parallel ablaufen, können wir nicht wissen, welche zuerst abgeschlossen werden. Wenn Sie dieses Programm ausführen, wird etwas Ähnliches wie das unten gezeigte gedruckt, obwohl die Ergebnisse von Lauf zu Lauf variieren können.Die
exec()
Familie der Systemaufrufe ersetzt den aktuell ausgeführten Code eines Prozesses durch einen anderen Code. Der Prozess behält seine PID bei, wird jedoch zu einem neuen Programm. Betrachten Sie beispielsweise den folgenden Code:Dieses Programm ruft die
execvp()
Funktion auf, um ihren Code durch das Datumsprogramm zu ersetzen. Wenn der Code in einer Datei mit dem Namen exec1.c gespeichert ist, führt die Ausführung zu der folgenden Ausgabe:Das Programm gibt die Zeile ―Ready to exec () aus. . . ‖ Ersetzt nach dem Aufruf der Funktion execvp () den Code durch das Datumsprogramm. Beachten Sie, dass die Zeile -. . . hat es funktioniert‖ wird nicht angezeigt, da zu diesem Zeitpunkt der Code ersetzt wurde. Stattdessen sehen wir die Ausgabe der Ausführung von "Datum -u".
quelle
fork()
::Es wird eine Kopie des laufenden Prozesses erstellt. Der laufende Prozess wird als übergeordneter Prozess und der neu erstellte Prozess als untergeordneter Prozess bezeichnet . Die Art und Weise, die beiden zu unterscheiden, besteht darin, den zurückgegebenen Wert zu betrachten:
fork()
Gibt die Prozesskennung (pid) des untergeordneten Prozesses im übergeordneten Prozess zurückfork()
gibt im Kind 0 zurück.exec()
::Es initiiert einen neuen Prozess innerhalb eines Prozesses. Es lädt ein neues Programm in den aktuellen Prozess und ersetzt das vorhandene.
fork()
+exec()
:Wenn Sie ein neues Programm starten, müssen Sie zunächst
fork()
einen neuen Prozess erstellen und dannexec()
(dh in den Speicher laden und ausführen) die Programmbinärdatei ausführen, die ausgeführt werden soll.quelle
Das beste Beispiel zu verstehen , das
fork()
undexec()
Konzept ist die Schale , Programm die Befehlsinterpreter , dass Benutzer führen typischerweise nach der Protokollierung in dem Shell interpretiert System das erste Wort der Kommandozeile als BefehlsnamenBei vielen Befehlen führen die Shell- Gabeln und der untergeordnete Prozess den dem Namen zugeordneten Befehl aus, wobei die verbleibenden Wörter in der Befehlszeile als Parameter für den Befehl behandelt werden.
Die Shell erlaubt drei Arten von Befehlen. Erstens kann ein Befehl eine ausführbare Datei sein , die Objektcode enthält, der durch Kompilieren des Quellcodes erzeugt wird (z. B. ein C-Programm). Zweitens kann ein Befehl eine ausführbare Datei sein, die eine Folge von Shell-Befehlszeilen enthält. Schließlich kann ein Befehl ein interner Shell-Befehl sein (anstelle einer ausführbaren Datei ex-> cd , ls usw.).
quelle