Gabel (Betriebssystem)

In der Computerwissenschaft, wenn sich ein Prozess gabeln, schafft er eine Kopie von sich. Mehr allgemein bedeutet eine Gabel in einer Nebenläufigkeitsumgebung, dass ein Faden der Ausführung kopiert wird, einen Kinderfaden vom Elternteilfaden schaffend.

Unter Unix und Unix ähnlichen Betriebssystemen können der Elternteil und die Kinderprozesse einander einzeln erzählen, indem sie den Rückwert des Systemanrufs untersuchen. Im Kinderprozess ist der Rückwert dessen 0, wohingegen der Rückwert im Elternteilprozess der PID des kürzlich geschaffenen Kinderprozesses ist.

Die Gabel-Operation schafft einen getrennten Adressraum für das Kind. Der Kinderprozess hat eine genaue Kopie aller Speichersegmente des Elternteilprozesses, obwohl, wenn copy-write Semantik durchgeführt wird, wirkliches physisches Gedächtnis nicht zugeteilt werden darf (d. h. beide Prozesse können dieselben physischen Speichersegmente eine Zeit lang teilen). Sowohl die Elternteil-als auch Kinderprozesse besitzen dieselben Codesegmente, aber führen unabhängig von einander durch.

Wichtigkeit vom Gabeln in Unix

Das Gabeln ist ein wichtiger Teil von Unix, der zur Unterstützung seiner Designphilosophie kritisch ist, die die Entwicklung von Filtern fördert. In Unix ist ein Filter (gewöhnlich klein) Programm, das seinen Eingang von stdin liest, und seine Produktion stdout schreibt. Eine Rohrleitung dieser Befehle kann durch eine Schale aneinander gereiht werden, um neue Befehle zu schaffen. Zum Beispiel kann man die Produktion des Befehls und den Eingang des Befehls aneinander reihen, einen neuen Befehl zu schaffen, der eine Zählung von Dateien drucken wird, die in ".cpp" enden, der im aktuellen Verzeichnis und irgendwelchen Unterverzeichnissen wie folgt gefunden ist:

$ finden. - Name "*.cpp" - drucken | WC-l

</Quelle>

Um das, die Schale-Gabeln selbst, und Gebrauch-Pfeifen, eine Form der Zwischenprozess-Kommunikation zu vollbringen, um die Produktion des Befehls zum Eingang des Befehls zu binden. Zwei Kinderprozesse, werden ein für jeden Befehl geschaffen (und). Diese Kinderprozesse werden mit dem Code überzogen, der mit den Programmen vereinigt ist, die sie beabsichtigt sind, um mit der Familie von Systemanrufen durchzuführen (im obengenannten Beispiel, wird den ersten Kinderprozess überziehen, und wird den zweiten Kinderprozess überziehen, und die Schale wird Pfeifen verwenden, um punktgleich zu sein, die Produktion dessen finden mit dem Eingang des WC).

Mehr allgemein wird das Gabeln auch durch die Schale jedes Mal durchgeführt, wenn ein Benutzer einen Befehl ausgibt. Ein Kinderprozess wird durch das Gabeln der Schale geschaffen, und der Kinderprozess, wird wieder durch mit dem mit dem Programm durchzuführend vereinigten Code überzogen.

Bearbeiten Sie Adressraum

Wann auch immer eine rechtskräftige Datei durchgeführt wird, wird es ein Prozess. Eine rechtskräftige Datei enthält binären Code, der in mehrere Blöcke gruppiert ist, genannt Segmente. Jedes Segment wird verwendet, für einen besonderen Typ von Daten zu versorgen. Einige Segment-Namen eines typischen ELFEN rechtskräftige Datei werden unten verzeichnet.

  • Text — Segment, das rechtskräftigen Code enthält
  • .bss — Segment, das Daten enthält, die zur Null initialisiert sind
  • Daten — Segment, das enthält, hat Daten initialisiert
  • symtab — Segment, das die Programm-Symbole (z.B enthält, fungieren Sie Name, Variablennamen, usw.)
  • interp — Segment, das den Namen des Dolmetschers enthält, der zu verwenden
ist

Der Befehl kann weitere Details der ELF-Datei zur Verfügung stellen. Wenn solch eine Datei im Gedächtnis für die Ausführung geladen wird, werden die Segmente im Gedächtnis geladen. Es ist für das komplette rechtskräftige nicht notwendig, in aneinander grenzenden Speicherpositionen geladen zu werden. Gedächtnis wird in gleiche große Teilungen genannt Seiten (normalerweise 4 Kilobytes) geteilt. Folglich, wenn das rechtskräftige im Gedächtnis geladen wird, werden verschiedene Teile des rechtskräftigen in verschiedene Seiten gelegt (der nicht aneinander grenzend sein könnte). Betrachten Sie einen ELFEN als rechtskräftige Datei der Größe 10K. Wenn die durch den OS unterstützte Seitengröße 4K ist, dann wird die Datei in drei Stücke (auch genannt Rahmen) der Größe 4K, 4K, und 2K beziehungsweise gespalten. Diese drei Rahmen werden in irgendwelchen drei freien Seiten im Gedächtnis angepasst.

Gabel und das Seitenteilen

Wenn ein Systemanruf ausgegeben wird, wird eine Kopie aller Seiten entsprechend dem Elternteilprozess geschaffen, in eine getrennte Speicherposition durch den OS für den Kinderprozess geladen. Aber das ist in bestimmten Fällen nicht erforderlich. Ziehen Sie den Fall in Betracht, wenn ein Kind einen "" Systemanruf durchführt (der verwendet wird, um jede rechtskräftige Datei aus einem C Programm durchzuführen), oder Ausgänge sehr bald nach. Wenn das Kind gerade erforderlich ist, um einen Befehl für den Elternteilprozess durchzuführen, gibt es kein Bedürfnis danach, die Seiten des Elternteilprozesses zu kopieren, da exec den Adressraum des Prozesses ersetzt, der es mit dem Befehl angerufen hat, durchgeführt zu werden.

In solchen Fällen hat eine Technik gerufen copy-write (KUH) wird verwendet. Mit dieser Technik, wenn eine Gabel vorkommt, werden die Seiten des Elternteilprozesses für den Kinderprozess nicht kopiert. Statt dessen werden die Seiten zwischen dem Kind und dem Elternteilprozess geteilt. Wann auch immer ein Prozess (Elternteil oder Kind) eine Seite modifiziert, wird eine getrennte Kopie dieser besonderen Seite allein für diesen Prozess gemacht (Elternteil oder Kind), der die Modifizierung durchgeführt hat. Dieser Prozess wird dann die kürzlich kopierte Seite aber nicht die geteilte in allen zukünftigen Verweisungen verwenden. Der andere Prozess (derjenige, der die geteilte Seite nicht modifiziert hat) setzt fort, die ursprüngliche Kopie der Seite zu verwenden (der jetzt nicht mehr geteilt wird). Diese Technik wird copy-write genannt, da die Seite kopiert wird, wenn etwas Prozess ihm schreibt.

Vfork und das Seitenteilen

ist ein anderer UNIX Systemanruf, der verwendet ist, um einen neuen Prozess zu schaffen. Wenn ein Systemanruf ausgegeben wird, wird der Elternteilprozess aufgehoben, bis der Kinderprozess entweder Ausführung vollendet hat oder durch ein neues rechtskräftiges Image über eine der Familie von Systemanrufen ersetzt worden ist. Sogar in werden die Seiten unter dem Elternteil- und Kinderprozess geteilt. Aber beauftragt copy-write nicht. Folglich, wenn der Kinderprozess eine Modifizierung in einigen der geteilten Seiten macht, wird keine neue Seite geschaffen, und die modifizierten Seiten sind zum Elternteilprozess auch sichtbar. Da es gar kein beteiligtes Seitenkopieren gibt (das Verbrauchen des zusätzlichen Gedächtnisses), ist diese Technik hoch effizient, wenn ein Prozess einen blockierenden Befehl mit dem Kinderprozess durchführen muss.

Auf einigen Durchführungen, ist dasselbe als.

Die Funktion unterscheidet sich von nur darin der Kinderprozess kann Code und Daten mit dem Benennen-Prozess (Elternteilprozess) teilen. Dieser eilen, Tätigkeit bedeutsam an einer Gefahr zur Integrität des Elternteilprozesses klonend, wenn missbraucht wird.

Dem Gebrauch zu jedem Zweck außer als eine Einleitung zu einem unmittelbaren Anruf zu einer Funktion von der Familie, oder dazu, wird nicht empfohlen. Insbesondere entmutigt die Mann-Seite von Linux für vfork stark seinen Gebrauch:

Die Funktion kann verwendet werden, um neue Prozesse zu schaffen, ohne den Adressraum des alten Prozesses völlig zu kopieren. Wenn ein gabelförmiger Prozess einfach dabei ist zu rufen, wird der Datenraum, der vom Elternteil dem Kind dadurch kopiert ist, nicht verwendet. Das ist in einer paginierten Umgebung besonders ineffizient, besonders nützlich machend. Abhängig von Größe des Datenraums des Elternteils, kann durch eine bedeutende Leistungsverbesserung übergeben.

Die Funktion kann normalerweise gerade wie verwendet werden. Es arbeitet jedoch nicht, um zurückzukehren, während es im Zusammenhang des Kindes vom Anrufer dessen läuft, da die schließliche Rückkehr davon dann bis einen nicht mehr gegenwärtigen Stapel-Rahmen zurückkehren würde. Sorge muss auch in den Anruf gebracht werden, aber nicht wenn seit dem Erröten nicht genannt werden kann und Standardeingabe/Ausgabe-Kanäle schließt, dadurch die Standardeingabe/Ausgabe-Datenstrukturen des Elternteilprozesses beschädigend. (Sogar mit ist es noch falsch zu rufen, da gepufferte Daten dann zweimal gespült würden.)

Wenn Signaldressierer im Kinderprozess danach angerufen werden, müssen sie denselben Regeln wie anderer Code im Kinderprozess folgen.

MMUless Systeme

Auf mehreren eingebetteten Geräten gibt es keine Speicherverwaltungseinheit, die eine Voraussetzung ist, für die copy-write Semantik durchzuführen, die dadurch vorgeschrieben ist. Wenn das System einen anderen Mechanismus für Adressräume pro Prozess wie ein Segment-Register hat, erreicht das Kopieren des kompletten Prozess-Gedächtnisses zum neuen Prozess die gewünschte Wirkung, jedoch ist das eine kostspielige Operation und am wahrscheinlichsten nicht benötigt vorausgesetzt, dass der neue Prozess fast sofort das Prozess-Image in den meisten Beispielen ersetzt.

Wenn alle Prozesse einen einzelnen Adressraum teilen, dann konnte der einzige Weg durchgeführt werden würde sein, die Speicherseiten zusammen mit dem Rest des Aufgabe-Zusammenhang-Schalters zu tauschen. Anstatt das zu tun, lassen eingebettete Betriebssysteme wie uClinux gewöhnlich weg und führen nur durch; ein Teil der Arbeit, die zu solch einer Plattform nach Backbord hält, schließt Neuschreiben-Code ein, um die Letzteren zu verwenden.

Sich in anderen Betriebssystemen gabelnd

Der Gabel-Mechanismus (1969) in Unix und Linux erhält implizite Annahmen auf der zu Grunde liegenden Hardware aufrecht: Geradliniges Gedächtnis und ein Paginierungsmechanismus, die eine effiziente, Speicherkopie-Operation eines aneinander grenzenden Adressbereichs ermöglichen. Im ursprünglichen Design des VMS (jetzt OpenVMS) Betriebssystem (1977) wurde eine Kopie-Operation mit der nachfolgenden Veränderung des Inhalts von einigen spezifischen Adressen für den neuen Prozess als im Gabeln unsicher betrachtet. Fehler im aktuellen Prozess-Staat können zu einem Kinderprozess kopiert werden. Hier wird die Metapher des Prozess-Laichens verwendet: Jeder Bestandteil des Speicherlay-Outs des neuen Prozesses wird kürzlich von Kratzer gebaut. Aus einem Softwaretechnikgesichtspunkt würde diese letzte Annäherung sauberer und sicher betrachtet, aber der Gabel-Mechanismus ist noch wegen seiner Leistungsfähigkeit vorherrschend. Die Laich-Metapher wurde später in Microsoft Betriebssysteme (1993) angenommen.

Anwendungsgebrauch

Die Gabel Systemanruf nimmt kein Argument und gibt einen Prozess-Personalausweis zurück, der gewöhnlich ein Wert der ganzen Zahl ist. Der zurückgegebene Prozess-Personalausweis ist des Typs pid_t, der in der Kopfball-Datei, sys/types.h definiert worden ist.

Der Zweck der Gabel Systemanruf ist, einen neuen Prozess zu schaffen, der der Kinderprozess des Anrufers wird, nach dem beide, die Elternteil- und Kinderprozesse, den Code im Anschluss an die Gabel Systemanruf durchführen werden. Folglich ist es wichtig, zwischen dem Elternteil- und Kinderprozess zu unterscheiden. Das kann durch die Prüfung des Rückwerts der Gabel Systemanruf getan werden.

  • Wenn Gabel einen negativen Wert zurückgibt, zeigt sie an, dass die Entwicklung des Prozesses erfolglos war.
  • Gabel gibt eine Null in den kürzlich geschaffenen Kinderprozess zurück.
  • Gabel gibt einen positiven Wert, den Prozess-Personalausweis des Kinderprozesses dem Elternteil zurück.

Beispiel in C

  1. einschließen
einschließen einschließen einschließen einschließen

int Haupt(Leere)

{\

pid_t pid;

/* Produktion sowohl vom Kind als auch vom Elternteilprozess

* wird der Standardproduktion, geschrieben

* als sie beide geführt zur gleichen Zeit.

*/

pid = Gabel ;

wenn (pid ==-1)

{

/* Fehler:

*, Wenn Gabel -1 zurückkehrt, hat ein Fehler zufällig

* (zum Beispiel hat die Zahl von Prozessen die Grenze erreicht).

*/

fprintf (stderr, "kann sich, Fehler %d\n", errno nicht gabeln);

Ausgang (EXIT_FAILURE);

}\

wenn (pid == 0)

{\

/* Kinderprozess:

*, Wenn Gabel 0 zurückkehrt, sind wir in

* der Kinderprozess.

*/

interne Nummer j;

für (j = 0; j

Beispiel in Perl

  1. !/usr/bin/env perl-w

verwenden Sie streng;

wenn (Gabel) {# Elternteil bearbeitet

foreach mein $i (0.. 9) {\

Druck "Elternteil: $i\n";

Schlaf 1;

}\

}\

sonst {# Kinderprozess

foreach mein $i (0.. 9) {\

Druck "Kind: $i\n";

Schlaf 1; }\

Ausgang (0); # Ende der gabelförmige Prozess

}\

Ausgang (0); # Ende der Elternteilprozess.

</Quelle>

Beispiel in der Pythonschlange

  1. !/usr/bin/env-Pythonschlange
  2. - das *-Codieren: Utf-8-* -

importieren Sie os, Zeit

def createDaemon :

" ""

Diese Funktion schafft einen Dienst/Dämon, der eine det. Aufgabe durchführen wird

" ""

Versuch:

# versorgen die Gabel PID

pid = os.fork

wenn pid> 0:

drucken Sie 'PID: %d' % pid

os. _ Ausgang (0)

außer OSError, Fehler:

drucken Sie 'Unfähig sich zu gabeln. Fehler: %d (%s)' % (error.errno, error.strerror)

os. _ Ausgang (1)

doTask

def doTask :

" ""

Diese Funktion schafft eine Aufgabe, die ein Dämon sein wird

" ""

# öffnen Sich die Datei darin schreiben Weise

Datei = offen ('/tmp/tarefa.log', 'w')

während Wahr:

Druck>> Datei, time.ctime

file.flush

time.sleep (2)

# Nahe die Datei

file.close

wenn __ __ == '__ wichtig __' nennen:

# schaffen den Dämon

createDaemon

</Quelle>

Siehe auch

  • Kinderprozess
  • Elternteilprozess
  • Gabel-Bombe
  • Gabel-exec
  • Exec
  • Ausgang
  • Warten Sie
auf

Links


Gabel (Softwareentwicklung) / Gabel (Begriffserklärung)
Impressum & Datenschutz