Linux select() und istream und Callbackfunktionen
-
Hallo,
ich habe relativ viel Erfahrung in C aber fast keine in C++, deshalb möchte ich für mein aktuelles Projekt c++ einsetzten um meine Fähigkeiten zu verbessern. Leider stoße ich schon bei der konzeption auf ziemlich große Hürden.Mein erstes Problem ist das ich keinen Weg gefunden habe den Filedescriptor von ifstream zurück geliefert zu bekommen. Was ich gefunden habe war ein Weg aus dem descriptor über umwege wieder einen ifstream zu machen. Das ist aber sehr unhandlich. Gibt es da nicht irgendwas kompaktes? Das Ziel ist es mittels select() auf die Lesbarkeit des streames zu warten und dabei möglichst wenig Rechenzeit zu verschwenden.
Das zweite Problem ist etwas aufwendiger zu erklären.
Ich habe 3 unterschiedliche Klassen von denen ich jeweils ein Objekt erstellt habe.Ich nenne sie mal control, keyboard und webif.
keyboard und webif enthalten jeweils eine Befehlsliste die der Reihe nach an control weiter gegeben werden soll. Dieser Befehl wird verarbeitet und an einen Treiber weiter gegeben.
Wenn die Ausführung abgeschlossen ist soll den klassen webif und keyboard signalisiert werden das sie das nächste Kommando aus der Liste senden können.Ich habe mir das so vorgestellt:
1. webif ruft eine Funktion von control auf um ein Kommando zu übergeben, dabei übergibt es einen Zeiger auf sich selbst und eine seiner funktionen
2. control führt das kommando aus
3. control ruft die funktion "void next()" von webif auf.Analog auch bei keyboard, auch keyboard enthält eine funktion "void next()"
Ich habe hierzu die Signale der Boostlibrary gefunden, damit würde das zwar schön funktionieren ich möchte aber dabei ja was lernen.
Wie würdet ihr das Problem lösen? Würdet ihr mir bitte ein kurzes Beispiel dazu geben?
Danke für eure Hilfe.
Basti
-
- Mit Standardmitteln kommt man AFAIK nicht an die files desciptoren.
- C++ funktioniert im wesentlichen wie C: wenn eine Funktion eine andere aufruft, die eine andere aufruft, die eine andere aufruft, ... läuft dir irgendwann der Stack über. Da hilft es auch nicht, wenn die Boost signals Funktionen noch dazwischen liegen. Was du suchst sind möglicherweise Events.
-
In der Standardbibliothek ist alles Betriebssystemspezifische weitgehend weggekapselt. Du wirst daher nicht so leicht an den unterliegenden Filedeskriptor eines ifstream kommen. Der kanonische Weg wäre umgekehrt, einen Filedeskriptor zu nehmen und einen Stream drumherum zu packen (genau das ist ein ifstream). Die Boost-Bibliothek bietet so etwas auch schon fertig, so dass man eigene Filedeskriptoren in Streams packen kann. So brauchst man das nicht alles selber schreiben. Ich weiß nicht, wie da die Möglichkeiten sind, das select passend einzubauen. Die Boost-Bibliotheken sind sehr mächtig und abstrakt. Es ist daher anzunehmen, dass es möglich ist, aber es wird sicher nicht einfach heraus zu finden, wie genau es geht.
Das Ziel ist es mittels select() auf die Lesbarkeit des streames zu warten und dabei möglichst wenig Rechenzeit zu verschwenden.
Das verstehe ich sowieso nicht genau. Würde dein Programm währenddessen etwas anderes machen? Der Stream wartet sowieso, wenn keine Daten da sind (was anderes bleibt ihm ja auch gar nicht übrig). Du scheinst ein Problem zu lösen, welches schon längst gelöst bzw. gar nicht vorhanden ist.
Deine andere Frage:
Warum holt sich control nicht selber das nächste Kommando, wenn es fertig ist?
-
manni66 schrieb:
- C++ funktioniert im wesentlichen wie C: wenn eine Funktion eine andere aufruft, die eine andere aufruft, die eine andere aufruft, ... läuft dir irgendwann der Stack über. Da hilft es auch nicht, wenn die Boost signals Funktionen noch dazwischen liegen. Was du suchst sind möglicherweise Events.
Nein, darauf läuft es nicht hinaus. Der Funktionsstapel wird zwischendrin wieder vollständig abgebaut. Die Ausführungsdauer eines Kommandos beträgt mehrere Sekunden. Ja, es handelt sich hier um events. Leider habe ich im c++ standard keine events entdeckt.
Bsp:
1. webif ruft control.start("Zeiger auf Webif funktion") auf
2. control.start() merkt sich den Zeiger, rechnet ein paar sachen aus und stößt die Ausführung an (signalisierung an anderes Programm), damit ist die Funktion beendet
3. Die Ausführung erfolgt durch ein anderes Programm, wenn es fertig ist signalisiert es das
4. Aufruf einer control-Funktion (letzten Endes durch ein select() das feststellt das in einer Pipe Daten warten) -> diese verarbeitet die Daten und weiß nun das der letzte Befehl korrekt ausgeführt wurde
5. control signalisiert dem ursprünglichen Aufrufer (webif) das sein Befehl ausgeführt wurde
6. webif entscheidet was nun zu tun istSeppJ schrieb:
Das Ziel ist es mittels select() auf die Lesbarkeit des streames zu warten und dabei möglichst wenig Rechenzeit zu verschwenden.
Das verstehe ich sowieso nicht genau. Würde dein Programm währenddessen etwas anderes machen? Der Stream wartet sowieso, wenn keine Daten da sind (was anderes bleibt ihm ja auch gar nicht übrig). Du scheinst ein Problem zu lösen, welches schon längst gelöst bzw. gar nicht vorhanden ist.
Ja es gibt mehrere Pipes und Sockets die aber nicht immer Lesbar sind. Ich weiß nie welches gerade Lesbar ist. Je nachdem welches Lesbar ist müssen natürlich unterschiedliche Dinge getan werden.
SeppJ schrieb:
Deine andere Frage:
Warum holt sich control nicht selber das nächste Kommando, wenn es fertig ist?Das wäre genauso möglich, das Problem bleibt aber das control wissen muss von wem es sich das nächste Kommando holt und über welche Funktion.
Das Ziel dabei soll es sein möglichst einfach neue Schnittstellen integrieren zu können. Mit diesem Konzept müsste ich nur eine neue Klasse schreiben die eine bestimmte callbackfunktion implementiert.