Seite 1 von 1
Pipes-And-Filter-Pattern...
Verfasst: So Jun 24, 2012 5:24 pm
von Leverator
Moin zusammen,
ich zerbreche mir gerade den Kopf darüber, wie ich am besten das Pipes-and-Filter Pattern in C++ unter Linux realisiere.
Was möchte ich machen:
Ich habe eine handvoll Module, die auf der einen Seite Daten (mehrere Datenströme) hinein bekommen, diese umrechnen und auf der anderen Seite Datenströme an das nächste Modul weiterreichen. Die Datenströme innerhalb des Modules müssen zwingend auf den Sample genau (Messignal - kein Audio; Anforderungen ähnlich) verarbeitet werden.
Das letzte Modul soll dann eine nette QT-Applikation sein, die mir das Ergebnis in Echtzeit präsentiert.
Ich schreibe hier so lässig Modul: Es sind in Wirklichkeit Shared-Objects, die während das Programm läuft eingeladen und ausgeführt werden können. - Je nach belieben des Nutzers. Somit kann z.B. im Live-Betrieb eine neuere Modul-Version angestartet werden.
Das Problem, vor dem ich gerade stehe ist folgendes:
Soll ich die geladenen Module jeweils als Threads oder als Prozess starten? Da ich oben bereits etwas von "Echtzeit" geschrieben habe, sollen die Daten so schnell es geht verarbeitet werden. Keine harten Echtzeitanforderungen, die besagen, daß innerhalb von ein paar Millisekunden das Ergebnis auf dem Schirm zu sein hat...
Nachteil bei Prozessen ist, daß ich noch eine komplette Kommunikationsinfrastruktur implementieren müsste, sodaß Signale ausgewertet oder gesendet werden können und Logging-Informationen an ein Logging-Interface versendet werden.
Bei Threads habe ich ein stdin und -out. Die Daten können über die lokalen Variablen weitergereicht werden, sodaß es hier auch keine Probleme gibt.
Welcher C++-Guru mag mich in diesem Sinne erleuchten?
Grüße,
Lev
Re: Pipes-And-Filter-Pattern...
Verfasst: So Jun 24, 2012 5:48 pm
von fat-lobyte
Da ich oben bereits etwas von "Echtzeit" geschrieben habe, sollen die Daten so schnell es geht verarbeitet werden.Keine harten Echtzeitanforderungen, die besagen, daß innerhalb von ein paar Millisekunden das Ergebnis auf dem Schirm zu sein hat...
Ich glaube viel wirst du hier auch nicht drehen können, außer dass du den Kernel höflich bittest, den Prozess mit niedrigem Nice-Wert den Vorzug zu geben.
Nachteil bei Prozessen ist, daß ich noch eine komplette Kommunikationsinfrastruktur implementieren müsste, sodaß Signale ausgewertet oder gesendet werden können und Logging-Informationen an ein Logging-Interface versendet werden.
Wie du im Titel erwähnt hast, könntest du die Standardeingabe und die Standardausgabe zur Ein/Ausgabe deines Datenstroms nutzen. Das machen einige Programme auch. Wenn du das mit einem fork(2) machst, könntest du hier auch alle Variablen übergeben. Die Priorität könntest du mit setpriority(2) setzen.
Wieso müsstest du eine komplette Kommunikationsinfrastruktur implementieren?
Bei Threads habe ich ein stdin und -out.
stdout hättest du bei einzelnen Prozessen auch, denn die Kindprozesse werden auf die gleiche Datei (oder Standardausgabe) schreiben, wie der Elternprozess.
Das Problem, vor dem ich gerade stehe ist folgendes:
Soll ich die geladenen Module jeweils als Threads oder als Prozess starten?
Ich glaube, hier wären eher Threads zu empfehlen, da du die Daten bereits lokal in deinem Prozessspeicher bereitgestellt hast. Auch müsste der Overhead zum starten/stoppen etwas geringer sein.
Der Nachteil wäre, dass du gegen Abstürze innerhalb der Module nichts machen kannst. Die Priorität könntest du mit pthread_setschedparam(3) setzen.
Kurz: ich sehe keinen Vorteil darin Prozesse zu bevorzugen.
Re: Pipes-And-Filter-Pattern...
Verfasst: So Jun 24, 2012 6:09 pm
von Leverator
Hi fat-lobyte!
Ich glaube, hier wären eher Threads zu empfehlen, da du die Daten bereits lokal in deinem Prozessspeicher bereitgestellt hast. Auch müsste der Overhead zum starten/stoppen etwas geringer sein.
Und ich erhoffe mir Zeitvorteile in einer Mehr-CPU-Umgebung, weil jeder Prozess seinen eigenen Speicherbereich hat in dem er arbeiten kann. Übergeben werden die Daten über Fifos. Jede CPU erhält genau die Daten, die sie für ihre Prozesse braucht.
Wenn jedoch nur Threads erzeugt werden, dann wird es einen Kommunikationsoverhead geben, wenn ein Thread auf eine andere CPU ausgelagert werden muss...
Wieso müsstest du eine komplette Kommunikationsinfrastruktur implementieren?
Die Fifos müssen eingerichtet werden, die Prozess-Signalauswertung - Signale an andere Prozesse senden-, Konfigurationsmöglichkeiten der einzelnen Module - und das Logging nicht vergessen, damit die Meldungen nicht im Chaos versinken...
Grüße,
Lev
Re: Pipes-And-Filter-Pattern...
Verfasst: So Jun 24, 2012 6:52 pm
von cloidnerux
Und ich erhoffe mir Zeitvorteile in einer Mehr-CPU-Umgebung, weil jeder Prozess seinen eigenen Speicherbereich hat in dem er arbeiten kann.
Wieso sollte das schneller sein? Alle Prozesse müssen über den selben Speicher-Bus auf den vergleichsweise langsamen Hauptspeicher zugreifen(im Vergleich zum Cache). Zudem musst du die Daten in einem Prozess erst hübsch verpacken, Serialisieren, nach außen Bringen und im anderen Prozess wieder entsprechend entgegen nehmen.
Hier musst du sogar noch mehr sicherstellen, dass der andere Prozess die Daten auch entsprechend schnell entgegen nimmt, denn nur weil er auf einem anderen Kern läuft, heißt es ja nicht, dass er nicht von irgendwas blockiert wird. Zudem kann der User einen Prozess abschießen, und du würdest evt nicht mal merken, dass dem so ist.
Threads bieten hier gewisse vorteile. Sie laufen auch auf mehreren Kernen, sie können aber auch Daten innerhalb des Programms durchreichen. Du kannst direkt Pointer auf entsprechende Datenstrukturen übergeben und weitermachen, ohne die Daten irgendwie neu zu verpacken. So zumindest meine Meinung.
MfG cloidnerux.
Re: Pipes-And-Filter-Pattern...
Verfasst: So Jun 24, 2012 7:09 pm
von fat-lobyte
Leverator hat geschrieben:Und ich erhoffe mir Zeitvorteile in einer Mehr-CPU-Umgebung, weil jeder Prozess seinen eigenen Speicherbereich hat in dem er arbeiten kann. Übergeben werden die Daten über Fifos. Jede CPU erhält genau die Daten, die sie für ihre Prozesse braucht.
Jede CPU enthält auch mit Threads genau die Daten, die sie braucht - jede CPU hat ihren eigenen Cache, ihre eigenen Register und spielt in ihrem "eigenen" Speicherbereicht (es kann auch der Teilbereich eines einzigen Prozesses sein). Mit Prozessen hast du im Gegenteil MEHR Wahrscheinlichkeit, dass sich der Kernel dazu entscheidet die CPU-Zeit einem anderen Prozess zu geben.
Leverator hat geschrieben:Wenn jedoch nur Threads erzeugt werden, dann wird es einen Kommunikationsoverhead geben, wenn ein Thread auf eine andere CPU ausgelagert werden muss...
Wie bereits von cloidnerux erwähnt, wirst du mit Prozessen auf jeden fall mehr Overhead haben, als mit Threads.
Wieso müsstest du eine komplette Kommunikationsinfrastruktur implementieren?
Die Fifos müssen eingerichtet werden, die Prozess-Signalauswertung - Signale an andere Prozesse senden-, Konfigurationsmöglichkeiten der einzelnen Module
Ja, da hast du schon recht, das ist ein Mehraufwand. Deswegen sind Threads auch IMHO geeigneter.
und das Logging nicht vergessen, damit die Meldungen nicht im Chaos versinken...
Wenn du irgendwas tolles machst, dann brauchst du in beiden Fällen Logging.
Re: Pipes-And-Filter-Pattern...
Verfasst: Mo Jun 25, 2012 6:07 am
von Fisherman
as letzte Modul soll dann eine nette QT-Applikation sein, die mir das Ergebnis in Echtzeit präsentiert.
Wenn du Qt verwenden möchtest, kannst du die
Threads gleich darüber laufen lassen. In Verbindung mit dem "Signal and Slot" Mechanismus von Qt sollte dein Programm "schnell genug" sein bzw. reagieren können.
Gleiches auch für deine Fifos - läßt sich wunderbar mit Qt realisieren.
Gruß