Ich habe Zsh-Modul geschrieben. Dort habe ich eine eingebaute Funktion, die dem Zsh Befehl zugeordnet ist. Diese Funktion dupliziert seine stdin Dateideskriptor:dup (fileno (stdin)) und dann spawnen von 32 Threads -> I/O-Fehler
/* Duplicate standard input */
oconf->stream = fdopen(dup(fileno(stdin)), "r");
Dann wird ein Faden wird hervorgebracht, die oconf
Struktur erhält. In diesem Thread, ich tun:
errno = 0;
/* Read e.g. 5 characters, putting them after previous portion */
int count = fread(buf + index, 1, read_size, oconf->stream);
/* Ensure that our whole data is a string - null terminated */
buf[ index + count ] = '\0';
if (errno) {
fprintf(oconf->err, "Read error (descriptor: %d): %s\n", fileno(oconf->stream), strerror(errno) >
}
Wenn I Laichen 32 Threads in zsh:
for ((i=1; i<=32; i ++)); do
ls -R /Users/myuser/Documents | mybuiltin -A myhash_$i $i
done
Dann 2-3 Fäden haben die I/O-Fehler aus dem obigen fprintf()
berichtet, zum Beispiel:
Lesefehler (Deskriptor: 7): Eingabe/Ausgabe-Fehler
Lesefehler (descriptor: 5): Ungeeignete ioctl für Geräte
Lesefehler (Deskriptor: 14): Ungeeignete ioctl für Geräte
Debugger sagt, dass diese Fäden, nach mehrfachen (5-20) fread() von Wiederholungen in Kernels __read_nocancel()
blockiert werden. Mit dem Dateideskriptor läuft also etwas wirklich Schlechteres.
Ansonsten funktioniert das. Die Pipe übergibt Daten korrekt von ls -R
, sie wird vom benutzerdefinierten Built-in gelesen. Wo ist die Gefahr? Wie kommt es, dass dup()
im Haupt-Thread führt zu etwas unlesbar zu fread()
führt? Ich könnte Zweifel haben, ob ich dup()
in sekundären Thread tun würde. Aber ich behalte das nur an einem sicheren Ort - Haupt-Thread, um dann bereit FILE *
Stream zu sekundären Thread zu übergeben. Auch mit POSIX open()
, read()
und close()
versucht, das Ergebnis ist das gleiche.