Moins!
Hat jemand hier extensiv mit pipes rumgemacht? Folgendes Problem (?): Ich muß zwischen einigen Prozessen strukturierte Daten austauschen und wüßte gern, ob es dafür eine "übliche" Vorgehensweise über pipes gibt. Mein Gedanke war, daß man erst eine Art ID in die pipe steckt, die bestimmt, was für Daten kommen werden, danach eine Längenangabe und erst dann die Daten. Hintergrund: Ein Prozess sammelt Daten und soll diese an einen zweiten Prozess, der die eintütet und ins Netz pumpt, übergeben. Die Daten an sich werden bereits vom ersten Prozess serialisiert/linearisiert, aber der zweite Prozess muß trotzdem wissen, was das für Daten sind, obwohl ihm der Inhalt egal ist. Auf der anderen Seite des Netzes soll das Ganze dann umgekehrt passieren. Warum das jeweils separate Prozesse sein müssen, kann ich jetzt nicht erklären, das ist etwas zu komplex, es ist jedenfalls zwingend so. Beipiel (stark vereinfacht und völlig aus der Luft gegriffen):
Der Datenserverprozess (wenn wir ihn mal so nennen wollen) will ein Datum (Singular von Daten, nicht Zeit) vom Typ struct {int a; float b; char c[42];} versenden. Etwas später sollen es X Instanzen von struct{int a; int b; float c;} sein, wobei X variabel ist. usw.
Wie gesagt sind es ca. 10 solcher strukturierter Datentypen, die in variabler Anzahl (aber dann immer "am Stück") versendet werden sollen. Ist dieses WRITEPIPE(id); WRITEPIPE(length); WRITEPIPE(data); /* data = BLOB */ doof? Wie würdet Ihr das lösen?
Hat überhaupt jemand kapiert, was ich mit diesem konfusen Text fragen will?
Gruß, Eric
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On Monday 25 March 2002 17:28, Eric Schaefer wrote:
Hat jemand hier extensiv mit pipes rumgemacht?
Ja. Und auch schon recht interessante Entdeckungen gemacht.
Beispiel: auf HP/UX verlieren Pipes, die zuviel Daten zu schnell transferieren sollen ab und zu einige Bytes. AF_LOCAL Sockets sind zuverlaessiger (man 2 socketpair).
Folgendes Problem (?): Ich muß zwischen einigen Prozessen strukturierte Daten austauschen und wüßte gern, ob es dafür eine "übliche" Vorgehensweise über pipes gibt.
Im Moment XML. Vorher ASCII. Weil halt Kompatibel (was bei lokalen Verbindungen aber wirklich keinen Sinn macht). Manchmal CORBA/DCOP/DCOM/etc.pp.
Pragmatiker nehmen serialisierte Binaerdaten irgendeiner Form.
Mein Gedanke war, daß man erst eine Art ID in die pipe steckt, die bestimmt, was für Daten kommen werden, danach eine Längenangabe und erst dann die Daten.
Klingt gut, ich haette die Laenge aber als erstes genommen, weil man dann ID und Daten auf einen Rutsch einlesen kann:
char buf[MAXTYPELEN+4]; int len,*id=(int*)buf; struct irgendwas *iwas=buf+sizeof(int); struct sonstwas *swas=buf+sizeof(int); read(fd,&len,sizeof(len)); read(fd,buf,len+sizeof(int)); switch(*id){ case IRGENDWAS: /*tu was mit *iwas */ break; /*...*/ }
Du siehst, eine Menge Casterei und wenig Speicherverbrauch...
...und zu wenig Kommentare: *id wird immer auf die ersten 4 Byte des Puffers zeigen, wo es auch geliefert wird *iwas und *swas zeigen immer auf den Anfang der Daten.
Eine andere Moeglichkeit waere ID und Laenge gemeinsam in eine struct{int id,len}; einzulesen und dann entweder a) fuer jede moegliche ID eine extra struct anlegen und lesen oder b) alle structs in einer union halten und nur ein read ausprogrammieren: union { struct irgendwas iwas; struct sonstwas swas; } alles; /*...*/ read(fd,&alles,len);
Hat überhaupt jemand kapiert, was ich mit diesem konfusen Text fragen will?
Ja, hast Du meine Antwort verstanden? ;-)
Konrad
- -- BOFH excuse #88:
Boss' kid fucked up the machine
On Mon, Mar 25, 2002 at 07:49:49PM +0100, Konrad Rosenbaum wrote:
Ja. Und auch schon recht interessante Entdeckungen gemacht.
Beispiel: auf HP/UX verlieren Pipes, die zuviel Daten zu schnell transferieren sollen ab und zu einige Bytes. AF_LOCAL Sockets sind zuverlaessiger (man 2 socketpair).
HP/UX steht sowieso nicht zur Debatte...
Ich muß zwischen einigen Prozessen strukturierte Daten austauschen und wüßte gern, ob es dafür eine "übliche" Vorgehensweise über pipes gibt.
Im Moment XML. Vorher ASCII. Weil halt Kompatibel (was bei lokalen Verbindungen aber wirklich keinen Sinn macht). Manchmal
Ja, lokal. XML wäre Oversized, ASCII hätte den Nachteil, daß unnötig konvertiert werden muß. Wenn ich so darüber nachdenke: Beim Versand übers Netz wäre ASCII aber sicher besser, da sich die Platform an der Senke langfristig gesehen ändern könnte...
CORBA/DCOP/DCOM/etc.pp.
ebenso wie RPC an der Stelle Bloat.
Pragmatiker nehmen serialisierte Binaerdaten irgendeiner Form.
Also wie unten?
char buf[MAXTYPELEN+4]; int len,*id=(int*)buf; struct irgendwas *iwas=buf+sizeof(int); struct sonstwas *swas=buf+sizeof(int); read(fd,&len,sizeof(len)); read(fd,buf,len+sizeof(int)); switch(*id){ case IRGENDWAS: /*tu was mit *iwas */ break; /*...*/ }
An genau sowas dachte ich. Ich wollte nur sicher gehen, daß es nicht irgendwas eleganteres gibt, was nicht gleich alles so aufplustert.
union { struct irgendwas iwas; struct sonstwas swas; } alles;
union == doof (persönliche Meinung/Antipathie)
Hat überhaupt jemand kapiert, was ich mit diesem konfusen Text fragen will?
Ja, hast Du meine Antwort verstanden? ;-)
Denke schon. ;-)
Vielleicht doch ASCII oder gar XML? Na mal sehen, wie sich das so anläßt...
Danke, Eric
On Mon, Mar 25, 2002 at 05:28:30PM +0100, Eric Schaefer wrote:
Moins!
Hat jemand hier extensiv mit pipes rumgemacht? Folgendes Problem (?): Ich muß zwischen einigen Prozessen strukturierte Daten austauschen und wüßte gern, ob es dafür eine "übliche" Vorgehensweise über pipes gibt.
Unter Unix läuft das normalerweise so ab: Du erstellst ein Socket-Paar. Dann machst du ein fork. Das fork gibt dir ein Eltern und ein Kindprozess. Die beiden können dann über die Sockets miteinander reden. Das Problem ist, dass du die Daten noch serializiere musst.
Du kannst natürlich das codieren und decodieren der Daten, bzw. marshalling, per Hand machen. Doch das haben andere schon vor dir programmiert.
Für python gibt es z.B. pyro (http://pyro.sourceforge.net/), bzw. xml-rpc client und server. Die arbeiten zwar über TCP/IP Sockets, das sollte über localhost aber auch sehr schnell sein.
thomas
On Mon, Mar 25, 2002 at 08:16:27PM +0100, Thomas Guettler wrote:
Unter Unix läuft das normalerweise so ab: Du erstellst ein Socket-Paar. Dann machst du ein fork. Das fork gibt dir ein Eltern und ein Kindprozess. Die beiden können dann über die Sockets miteinander reden. Das Problem ist, dass du die Daten noch serializiere musst.
Wie man Daten durch eine Pipe schiebt, ist mir schon klar. Mir ging es um:
Du kannst natürlich das codieren und decodieren der Daten, bzw. marshalling, per Hand machen. Doch das haben andere schon vor dir programmiert.
Für python gibt es z.B. pyro (http://pyro.sourceforge.net/), bzw. xml-rpc client und server. Die arbeiten zwar über TCP/IP Sockets, das sollte über localhost aber auch sehr schnell sein.
C bzw. C++?
Danke, Eric
lug-dd@mailman.schlittermann.de