GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Der Unterschied zwischen fork(), vfork(), exec() und clone()

  1. fork() - Erstellt einen neuen untergeordneten Prozess, der eine vollständige Kopie des übergeordneten Prozesses ist. Untergeordnete und übergeordnete Prozesse verwenden unterschiedliche virtuelle Adressräume, die anfänglich von denselben Speicherseiten gefüllt werden. Wenn dann beide Prozesse ausgeführt werden, beginnen sich die virtuellen Adressräume mehr und mehr zu unterscheiden, da das Betriebssystem ein verzögertes Kopieren von Speicherseiten durchführt, die von einem dieser beiden Prozesse geschrieben werden, und eine unabhängige Kopie der modifizierten Seiten zuweist Speicher für jeden Prozess. Diese Technik wird Copy-On-Write (COW) genannt.
  2. vfork() - Erstellt einen neuen untergeordneten Prozess, der eine "schnelle" Kopie des übergeordneten Prozesses ist. Im Gegensatz zum Systemaufruf fork() verwenden untergeordnete und übergeordnete Prozesse denselben virtuellen Adressraum. HINWEIS! Unter Verwendung desselben virtuellen Adressraums verwenden Eltern und Kind denselben Stapel, den Stapelzeiger und den Anweisungszeiger, wie im Fall des klassischen fork() ! Um unerwünschte Interferenzen zwischen Eltern- und Kindprozess zu verhindern, die denselben Stack verwenden, wird die Ausführung des Elternprozesses eingefroren, bis der Kindprozess entweder exec() aufruft (erstellen Sie einen neuen virtuellen Adressraum und einen Übergang zu einem anderen Stack) oder _exit() (Beendigung der Prozessausführung). vfork() ist die Optimierung von fork() für "fork-and-exec"-Modell. Es kann 4-5 Mal schneller ausgeführt werden als der fork() , weil anders als bei fork() (auch wenn COW im Hinterkopf behalten wird), Implementierung von vfork() Systemaufruf beinhaltet nicht das Anlegen eines neuen Adressraums (Zuweisung und Einrichtung neuer Seitenverzeichnisse).
  3. clone() - Erstellt einen neuen untergeordneten Prozess. Verschiedene Parameter dieses Systemaufrufs geben an, welche Teile des Elternprozesses in den Kindprozess kopiert werden müssen und welche Teile zwischen ihnen geteilt werden. Infolgedessen kann dieser Systemaufruf verwendet werden, um alle Arten von Ausführungseinheiten zu erstellen, beginnend mit Threads und endend durch vollständig unabhängige Prozesse. Tatsächlich clone() Systemaufruf ist die Basis, die für die Implementierung von pthread_create() verwendet wird und die ganze Familie des fork() Systemaufrufe.
  4. exec() - setzt den gesamten Speicher des Prozesses zurück, lädt und analysiert die angegebene ausführbare Binärdatei, richtet einen neuen Stack ein und übergibt die Kontrolle an den Einstiegspunkt der geladenen ausführbaren Datei. Dieser Systemaufruf gibt niemals die Kontrolle an den Aufrufer zurück und dient zum Laden eines neuen Programms in den bereits bestehenden Prozess. Dieses System rufen Sie mit fork() auf Systemaufruf bilden zusammen ein klassisches UNIX-Prozessverwaltungsmodell namens "fork-and-exec".

  • vfork() ist eine obsolete Optimierung. Vor guter Speicherverwaltung, fork() machte eine vollständige Kopie des Gedächtnisses der Eltern, also war es ziemlich teuer. da in vielen Fällen ein fork() gefolgt von exec() , das die aktuelle Speicherkarte verwirft und eine neue erstellt, war dies ein unnötiger Aufwand. Heute fork() kopiert den Speicher nicht; es wird einfach auf "copy on write" gesetzt, also fork() +exec() ist genauso effizient wie vfork() +exec() .

  • clone() ist der Systemaufruf, der von fork() verwendet wird . mit einigen Parametern erstellt es einen neuen Prozess, mit anderen erstellt es einen Thread. der Unterschied zwischen ihnen besteht lediglich darin, welche Datenstrukturen (Speicherplatz, Prozessorstatus, Stack, PID, geöffnete Dateien usw.) gemeinsam genutzt werden oder nicht.


  • execve() ersetzt das aktuelle ausführbare Image durch ein anderes, das aus einer ausführbaren Datei geladen wird.
  • fork() erstellt einen untergeordneten Prozess.
  • vfork() ist eine historisch optimierte Version von fork() , soll verwendet werden, wenn execve() wird direkt nach fork() aufgerufen . Es stellte sich heraus, dass es in Nicht-MMU-Systemen (wo fork() nicht effizient arbeiten kann) und wenn fork() Prozesse mit einem enormen Speicherverbrauch, um ein kleines Programm auszuführen (denken Sie an Javas Runtime.exec() ). POSIX hat den posix_spawn() standardisiert um diese letzten beiden moderneren Verwendungen von vfork() zu ersetzen .
  • posix_spawn() entspricht einem fork()/execve() , und erlaubt auch etwas fd-Jonglage zwischendurch. Es soll fork()/execve() ersetzen , hauptsächlich für Nicht-MMU-Plattformen.
  • pthread_create() erstellt einen neuen Thread.
  • clone() ist ein Linux-spezifischer Aufruf, mit dem alles ab fork() implementiert werden kann bis pthread_create() . Es gibt viel Kontrolle. Inspiriert von rfork() .
  • rfork() ist ein Plan-9-spezifischer Anruf. Es soll ein generischer Aufruf sein, der mehrere Grade der gemeinsamen Nutzung zwischen vollständigen Prozessen und Threads zulässt.

Linux
  1. Was ist der Unterschied zwischen Sudo Su – und Sudo Su –?

  2. Der Unterschied zwischen Getty und Agetty?

  3. Der Unterschied zwischen .exrc und .vimrc?

  4. Der Unterschied zwischen „$ . Foo‘ und ‚$ ./foo‘??

  5. Der Unterschied zwischen 'env' und 'printenv'?

Was ist der Unterschied zwischen Linux und Unix?

Was ist ein Hypervisor? Was ist der Unterschied zwischen Typ 1 und 2?

Was ist der Unterschied zwischen Curl und Wget?

Was ist der Unterschied zwischen strtok_r und strtok_s in C?

Was ist der Unterschied zwischen ls und l?

Was ist der Unterschied zwischen unlink und rm?