UNIXwork

Kind-Prozesse erstellen mit posix_spawn

01. Dezember 2019

Ich hatte mal eine Anleitung dazu geschrieben, wie mittels fork und exec Kind-Prozesse erstellt und Programme ausgeführt werden. In diesem Artikel möchte ich die Funktion posix_spawn vorstellen, die im Prinzip das gleiche kann und dabei ein paar Vorteile hat.

In Unix werden traditionell Programme ausgeführt, in dem der aktuelle Prozess geforked, also dupliziert, wird und im neuen Kind-Prozess wird ein anderes Programm-Image mittels exec geladen.

Das Problem an der Sache ist, dass fork mehr oder weniger Overhead haben kann, je nach Betriebsystem. Linux ist da recht effizient, es werden aber immer noch die Page Tables des Parent kopiert. Dazu kommt, dass es auch etwas umständlicher zu programmieren ist, als nur eine einzige Funktion aufzurufen.

Daher wurde irgendwann die Funktion posix_spawn eingeführt:

int posix_spawn(pid_t *pid, const char *path,
	   const posix_spawn_file_actions_t *file_actions,
	   const posix_spawnattr_t *attrp,
	   char *const argv[], char *const envp[]);

Um z.B. das Programm /bin/echo in einem separaten Prozess auszuführen, reicht folgender Code:

char *args[3];
args[0] = "echo";
args[1] = "Hello World";
args[2] = NULL;

pid_t pid; // child pid
posix_spawn(&pid, "/bin/echo", NULL, NULL, args, NULL);

Das ist ein sehr einfaches Beispiel. Was man eigentlich noch bräuchte, ist eine Möglichkeit, die Filedescriptoren für stdin, stdout und stderr zu modifizieren. Hierfür gibt es den Parameter file_action. Um den zu verstehen, sollte man sich noch mal anschauen, wie Programme mittels fork und exec ausgeführt werden, daher noch mal eine kleine Zusammenfassung meines Artikels dazu.

Stdin, stdout und stderr sind Filedescriptoren, die immer die Nummern 0, 1 und 2 haben. Mit der Funktion dup2 können wir einen Filedescriptor duplizieren und der Kopie eine exakte Nummer zuweisen. Was man also machen muss ist, vor dem Erstellen des neuen Prozesses erstmal neue Filedescriptoren für stdin/stdout/stderr zu erstellen (z.B. mit pipe oder open) und nach dem Erstellen des Kind-Prozesses aber noch vor exec werden mittels dup2 die Filedescriptoren auf die Positionen 0, 1 und 2 gelegt.

Der file_actions Parameter bei posix_spawn ist genau dafür gedacht. Diesem können Aktionen wie dup2 oder auch close und open zugeordnet werden, die dann nach dem Erstellen des Kind-Prozesses verarbeitet werden.

Zuerst muss file_actions hierfür initialisiert werden:

posix_spawn_file_actions_t actions;
posix_spawn_file_actions_init(&actions);

Danach können Actions zugewiesen werden:

// stderr im Kind-Prozess schließen
posix_spawn_file_actions_addclose(&actions, 2);

// stdout in die Datei out.txt umleiten
posix_spawn_file_actions_addopen(&actions, 1, "out.txt", O_CREAT|O_WRONLY, 0644);

Nach dem Ausführen von posix_spawn sollte der Speicher wieder freigegeben werden:

posix_spawn_file_actions_destroy(&actions);

Ich habe auch ein ausführliches Beispiel geschrieben, in dem die Ausgabe in eine Pipe mit Hilfe von posix_spawn_file_actions_adddup2 umgeleitet wird, die dann im Parent ausgelesen wird.

Autor: Olaf | 0 Kommentare | Tags: unix, c

FreeBSD und Mellanox ConnectX-2

17. August 2019

Ich war etwas überrascht, als FreeBSD meine Netzwerkkarte von Mellanox nicht erkannt hat. Die Mellanox ConnectX-2 ist vielleicht eine der verbreitetsten 10GbE-Netzwerkkarten.

FreeBSD unterstützt die natürlich auch, allerdings muss man da wieder manuell eingreifen. Es fehlt nur eine Zeile in der Datei /boot/loader.conf.

mlx4en_load="YES"

Nach einem Reboot wird der Treiber für die Netzwerkkarte geladen. Danach kann man sein Netzwerkinterface konfigurieren. In meinem Fall wollte ich DHCP und dafür waren folgende zusätzlichen Zeilen in /etc/rc.conf nötig:

ifconfig_mlxen0="DHCP"
ifconfig_mlxen0_ipv6="inet 6 accept_rtadv"

Danach noch folgenden Befehl ausführen:

service dhclient start mlxen0

Und das Netzwerk dürfte funktionieren.

Autor: Olaf | 0 Kommentare | Tags: freebsd, network

dav update 1.2.4

02. Juni 2019

Libcurl 7.62 hat leider eine kleine Änderung, die dazu führt, dass dav sich nicht mehr kompilieren lässt. Daher gibt es jetzt ein kleines Update dafür.

dav Projektseite SourceForge Projektseite

Autor: Olaf | 0 Kommentare | Tags: dav, curl

XNEdit Update 1.0.1

05. April 2019

Hat nicht lange gedauert, da gibt es schon ein kleines Update für XNEdit. Ein schwerer Fehler beim konvertieren von Dateikodierungen musste behoben werden. Wenn eine Datei mit einer anderen Kodierung als UTF-8 gespeichert werden sollte, wurden dabei ein paar Zeichen übersprungen.

Des Weiteren gibt es ein paar Detailverbesserungen, wenn die Locale-Encoding nicht UTF-8 ist.

XNEdit auf Sourceforge

Autor: Olaf | 0 Kommentare | Tags: xnedit, x11, unix, linux

Linkdump

13. März 2019
Autor: Olaf | 0 Kommentare | Tags: links, shell, bash, c, sun
Zurück Weiter