Der Kernel tut normalerweise wenig oder gar keine Pufferung auf Zeichengeräten.
Der Kernel macht beim Lesen von Dateien in Dateisystemen eine gewisse Pufferung.
Sie können nicht sagen, welche Art von Gerät Standardeingabe ist, da es von Prozess zu Prozess variiert. Standardmäßig ist fd 0 normalerweise die Tastatur des Benutzers, bei der es sich um ein Zeichengerät handelt. Aber wenn ich sage
program < file
dann ist fd 0 eine gewöhnliche Datei. Wenn ich sage
dann ist fd 0 ein Blockgerät. Und wenn ich daran arbeiten würde, könnte ich wahrscheinlich auch fd 0 an einen Netzwerkanschluss anschließen.
In Linux gibt es auch /proc/pid/fd/0
, aber das ist auch kein Gerät; es sieht aus wie ein Symlink zu dem tatsächlichen Gerät in /dev
, was auch immer es ist.
Nachtrag: ob ein bestimmtes Gerät gepuffert wird oder nicht hängt wirklich davon ab, wie der Treiber für das Gerät geschrieben. Jeder gegebene Treiber kann irgendeine Form der Pufferung implementieren oder nicht. Ob die Pufferung tatsächlich verwendet wird, hängt möglicherweise auch von anderen Faktoren ab.(Zum Beispiel sind die Unix-Terminal-Treiber alle standardmäßig gepuffert, aber diese Pufferung ist ausgeschaltet, wenn Sie den Treiber in den "cbreak" oder "raw" Modus setzen). Ich glaube nicht, dass Sie allgemeine Aussagen machen können, dass Zeichen- oder Blockgeräte gepuffert sind oder nicht.
Nachtrag 2: Wenn Sie anfangen, die Schichten abzuschälen, kann es ziemlich kompliziert werden. Unix bemüht sich mächtig (und macht in der Regel einen sehr guten Job), das richtige Gleichgewicht zwischen "Do-Was-Ich-Mittel" gegen "Keep-It-Simple" zu finden. Zum Beispiel, wenn Sie ein Terminal haben, das ist nicht Linie-gepuffert, und Sie fragen nach 10 Zeichen, aber es gibt nur 3 verfügbar, read()
wird zurückgeben 3. Was ist das Richtige, aber es deutet darauf hin, dass es immer noch ein Puffer irgendwo, wo diese drei Zeichen zwischen der Zeit, die sie eingegeben wurden und der Zeit, die Sie sie gelesen haben. Außerdem, wenn Sie nur 3, aber 10 verfügbar waren, denke ich, dass unter anderen Umständen die anderen 7 für Sie gespeichert werden, was wiederum eine ziemlich große Menge an Kernel-Level-Pufferung nahelegt.
Aber im Rohmodus bin ich ziemlich sicher, dass Sie Zeichen verlieren können, wenn Sie sie nicht schnell genug lesen. Ich habe meine Aufmerksamkeit vom Terminaltreiber auf Netzwerk-Sockets gerichtet und dachte, dass unter bestimmten Umständen, wenn Sie einen read()
auf einem UDP-Modus-Socket machen und das tatsächliche UDP-Paket größer als Ihre Leseanforderung ist, Sie den Rest des Pakets verlieren können da auch. [Obwohl ein Kommentator suggeriert, dass ich falsch liegen könnte.] (TCP-Modus-Buchsen, auf der anderen Seite, sind offensichtlich sehr stark gepuffert!)
Also, unter dem Strich: die Regeln können kompliziert sein, und die genauen Details hängen definitiv nicht ab nur der bestimmte Gerätetreiber im Einsatz, aber möglicherweise auch unzählige andere Details.
'stdin' ist ein * stream *, kein * Gerät *. –
_ "dem Kernel ist es egal, von was er liest, solange es ein Block-Gerät oder eine Datei auf einem Block-Gerät ist." _ Das ist nicht ganz richtig; Es gibt verschiedene Arten von Dateideskriptoren (Sockets, unbenannte Pipes, 'signalfd's,' eventfd's, 'epoll' Deskriptoren usw.), die keine Datei irgendwo im Dateisystem haben. Entscheidend ist, dass Sie einen Dateideskriptor haben und das Lesen unterstützt. –
@PaulR Danke! Bearbeitet die Frage :) –