Wie buffern eigentlich Brenner?
-
In so einem Fall wäre eine Thread-Synchronisation tatsächlich überflüssig.
-
Bei nem Ring musst du auch synchronisieren, sonst überschreibst du was, was noch nicht gelesen wurde oder liest was, was noch nicht geschrieben wurde. Außer wenn die Operationen zu Setzen und Vergleichen der Schreib/Lese-Pointer atomar sind. Aber eigentlich entspricht das warten auch einer Thread-Sync. nur ohne Mutex.
-
Nein, du überschreibst nichts was noch nicht gelesen wurde. Es läuft so:
Wenn du etwas liest entfernst du es auch gleichzeitig aus dem Ring. Du schreibst nur wenn die Queue nicht voll ist. Wenn die Queue voll ist wartest du einfach bis wieder was gelesen wurde und somit überschreibst du nichts. Wenn die Queue leer ist wartest du mit lesen.
Da der Lese- und Schreib-Thread in die gleiche Richtung laufen gibt es also keine Probleme, da durch das Warten bei den oben genannten Bedingungen, der Lese-Thread nie den Schreib-Thread "überholt" und umgekehrt. Der Lese-Thraead liest also immer "hinter" dem Schreib-Thraead.
Hmm... etwas wirre Erklärung aber ich hoffe es hilft.
-
Dann muss aber das setzen/lesen, ob die Queue leer oder voll ist bzw. bis wo man schreiben darf atomar sein.
-
dEUs schrieb:
Wie kommst du darauf?
Weil ein Brenner eben nicht über klassische Shared-Memory-Datenstrukturen mit dem PC kommuniziert, sondern über einen IDE/SATA/SCSI Controller.
Also genaugenommen redet der PC mit dem Controller (über PCI/PCI-X/PCIe/USB/...) und der Controller dann mit dem Brenner (über IDE/SATA/SCSI/...).
Und die Protokolle die zur Kommunikation zwischen PC <-> Controller bzw. Controller <-> Brenner verwendet werden, verwenden üblicherweise keine Mutexen o.ä.
Statt dessen gibt es Controller-Status Register und dergleichen.Im Prinzip könnte man genauso fragen ob zwischen HTTP-Server und HTTP-Client Locks verwendet werden, und einer den anderen blockieren kann. Da gibts ja auch zumindest zwei Threads die parallel laufen (einer am Client, einer am Server), und es werden auch in beide Richtungen Daten übertragen (z.B. HTTP GET/HTTP POST). Trotzdem gibt es keine klassischen Locks zwischen Client und Server, und der Server kann es leicht so einrichten, dass ihn ein Client nicht blockieren kann. Genau so kann es ein Client einrichten dass ihn der Server nicht blockieren kann. Sogar wenn beide wirklich nur einen Thread verwenden (man kann ja z.B. pollen oder asynchrone IO Funktionen verwenden).
Und nun denk dir Statt dem Controller einen HTTP Proxy, statt dem Brenner einen HTTP-Server und statt dem Bus und SATA Kabel je ein Netzwerk-Kabel.
Klar gibt es 100 Sachen die im Detail anders sind, aber vom Prinzip her unterscheiden sich Client/Server Anwendungen nicht besonders vom Ansprechen von Peripherie.
-
z.T. Ring-Puffer: es werden in diesen Protokollen auch keine Ring-Puffer verwendet, zumindest wäre es mir neu. Ist auch nicht nötig. Auch braucht man keine atomaren Befehle. Der Fall ist ja denkbar einfach, es gibt nur einen "Master" (PC), einen "Slave" (Controller), Sichtbarkeit von Änderungen im Speicher ist kein echtes Problem, IO Register werden nicht gecached, was will man mehr. OK, das Schreiben bzw. Lesen von IO Registern muss natürlich atomar sein. Das ist es auch, dafür sorgt die Hardware.
Eine genauere Erklärung würde wohl etwas zu weit führen. Lest euch einfach mal durch wie der PC mit z.B. einem IDE Controller kommuniziert, das sollte zum Verständnis reichen.
-
Beim Buffern fürs CD-Brennen geht es auf SW-Seite doch erst mal nur darum, dass Daten schon vor dem Brennen (teilweise) in den Arbeitsspeicher geladen werden, weil die Platte zu langsam sein könnte. Das kann man mit Ring-Buffern, Mutexen oder sonst was machen, dürfte relativ egal sein.
Wie das ganze Hardwareseitig aussieht, weiß ich nicht wirklich. Aber ich denke nicht, dass der Brenner direkt auf den Arbeitsspeicher zugreift (Nachdem was hustbaer schreibt ist es wohl auch nicht so).
CD-Brenner werden intern wahrscheinlich einen eigenen Buffer haben, den man immer wieder echtzeitig befüllen muss. Das befüllen dieses Buffers dürfte dann über PCI/PCI-X/PCIe/USB/...) und (IDE/SATA/SCSI/...) gehen.
-
aber schrieb:
Wie das ganze Hardwareseitig aussieht, weiß ich nicht wirklich. Aber ich denke nicht, dass der Brenner direkt auf den Arbeitsspeicher zugreift (Nachdem was hustbaer schreibt ist es wohl auch nicht so).
Naja jain
Mein Vergleich war dazu gedacht eine Vorstellung zu vermitteln wieso man zwischen PC und HDD/Brenner/... keine klassischen Mutexen braucht, und auch nicht einer den anderen blockieren kann.Real gibt es schon DMA, also Mechanismen mittels derer z.B. der Laufwerks-Controller direkt auf den Hautspeicher zugreifen kann (bzw. genau so Grafikkarten, Netzwerkkarten etc.). Das tut er allerdings nur auf Anweisung des PCs, d.h. man braucht dazu auch wieder keine klassischen Locks (Mutexen o.ä.).
CD-Brenner werden intern wahrscheinlich einen eigenen Buffer haben, den man immer wieder echtzeitig befüllen muss.
Genau. Der Brenner hat nen Puffer der er selbst ganz alleine verwaltet. Wenn da Platz frei ist, dann kann der PC den Brenner (genauer: Controller) anweisen da weitere Daten reinzuschreiben. (Bzw. ohne DMA schreibt der PC selbst die Daten da rein. Allerdings indirekt, indem er ein BYTE/WORD/DWORD/... nach dem anderen in ein IO Register des Controllers schreibt.)
Dass der Brenner seinen eigenen Puffer hat, und den auch selbst verwaltet, mach auch "Buffer underrun Protection" möglich. Wenn der Brenner sieht, dass die Daten im Puffer nur mehr für N Sektoren reichen, leitet er eine "kontrollierte Schreibpause" ein. Und sobald der Puffer dann wieder voll ist, schreibt er dort weiter wo er aufgehört hat.
-
Muss man, wenn man eine CD Brenner SW wie Nero schreibt, diese so ähnlich wie einen Treiber schreiben, oder bieten Betriebssystem (Win/Linux) schon APIs an um auf solche IO Register zuzugreifen?
-
Danke an euch alle für den informativen und lebhaften Gedankenaustausch. Selten, dass ein Thread so gut wird, wie erhofft. Besonders überzeugt hat mich hustbaer!
Frohes Neues und guten Rutsch wünsch ich!