FIFO-Problem
-
Ich hab ein ganz einfaches FIFO-Problem. Zwei Programme
waren erstellt eine FIFO "waren.fifo", ließt Zeilen von der Standardeingabe bis 0 eingegeben wird und schreibt die in die FIFO.
inventur ließt von der FIFO und schreibt alles in eine Datei (bzw. erstmal reicht der Screen). Wenn niemand mehr auf die FIFO schreibt beendet das Programm, also erst wenn waren.exe geschlossen ist.
Hab bisher das hier, funktioniert aber nicht wie es soll [siehe unten]:
// waren: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int main () { mkfifo("WAREN.FIFO",0777); // FIFO erstellen long int warnr = -1; unsigned long int warstueck = 0; FILE* fifo = fopen("WAREN.FIFO","w"); // öffnen, while(warnr != 0) { char line [80]; printf("INPUT (Form: WarenNr:Stueckzahl):\n"); scanf("%s",line); // brav einlesen sscanf(line,"%d:%d",&warnr,&warstueck); // schauen ob eh nicht 0 eingegeben wurde für warnr if(warnr != 0) { fputs(line,fifo); // in FIFO schreiben } fflush(fifo); // damits der gegenüber sofort lesen kann } fclose(fifo); // brav schließen am ende return(0); } // inventur: #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> int main () { // fifo nonblocking öffnen int fifo = open("WAREN.FIFO",O_RDONLY | O_NONBLOCK); // hier ausgelesene daten reinschreiben FILE* writeto = fopen ("Warenbestand.dat","w"); char zeichen = ' '; long int len = 0; while(true) { // lesen von fifo len = read(fifo,&zeichen,1); // wenns nicht mehr geht == EOF und die fifo zu ist und nicht nur grad keine daten da sind beenden if(len == 0 && errno != EAGAIN) break; if(len > 0) // juhu daten da { // ausgeben fprintf(writeto,"%c",zeichen); printf("%c",zeichen); } } // schließen close(fifo); fclose(writeto); return(0); }
Probleme:
inventur beendet nicht wenn waren beendet
inventur gibt Daten nicht ausMfG SideWinder
-
man: read(2) liefert -1 bei einem Fehler, darauf solltest du prüfen.
btw. immer nur 1 byte zu lesen ist nicht gerade ideal!
-
Das Problem liegt bei inventur, lese ich die FIFO mit cat funktioniert die Sache nämlich schon.
Derzeit bin ich bei folgendem inventur:
int fifo = open("WAREN.FIFO",O_RDONLY | O_NONBLOCK); FILE* writeto = fopen ("Warenbestand.dat","w"); char zeichen = ' '; long int len = 0; while(true) { len = read(fifo,&zeichen,1); //printf("%d Zeichen gelesen.",len); // Funktioniert if(len > 0) { printf("Zeichen gelesen."); // Funktioniert nicht mehr fprintf(writeto,"%c",zeichen); printf("%c",zeichen); } } close(fifo); fclose(writeto); return(0);
len ist niemals >0
MfG SideWinder
-
Jetzt springst du ja garnicht mehr aus der Schleife raus -> es wird auch nie geflusht.
Machso so:if(len == 0) break; if(len > 0) write(...);
-
ausserdem wäre select() hier auch angebrachter als diese cpu-fressende Schleife (sofern du das überhaupt nicht-blockierend brauchst).
-
Geflushed wird bei mir sowieso nur in waren und nicht in inventur? Oder liegt hier der Fehler?!
Edit: Mit deiner Änderung gibt er immer erst aus wenn ich waren schließe - y that?
MfG SideWinder
-
Bei close() in Invenur wird automatisch geflusht.
-
DrGreenthumb schrieb:
ausserdem wäre select() hier auch angebrachter als diese cpu-fressende Schleife (sofern du das überhaupt nicht-blockierend brauchst).
Nein aber nmorgen benötige ich auch Non-Blocking-FIFOs und die soll ich ja auch üben für meinen Test
MfG SideWinder
-
Edit: Mit deiner Änderung gibt er immer erst aus wenn ich waren schließe - y that?
printf() ohne einem \n flusht nix. Deshalb auch erst die Ausgabe beim Beenden.
-
DrGreenthumb schrieb:
Edit: Mit deiner Änderung gibt er immer erst aus wenn ich waren schließe - y that?
printf() ohne einem \n flusht nix. Deshalb auch erst die Ausgabe beim Beenden.
omg das wars.
Ausgabe immer erst am Ende weil ich brav zeichenweise gelesen habe und kein Newline gemacht habe -> das spar ich mir jetzt indem ich einfach zeilenweise lese *g*.
Und das inventur nicht beendete lag offenbar an && errno != EAGAIN - wann muss ich überhaupt auf EAGAIN prüfen?
MfG SideWinder
-
EAGAIN Non-blocking I/O has been selected using O_NONBLOCK and no data
was immediately available for reading.
-
Das hab ich auch gelesen - bloß darf ichs ja genau dann nicht einsetzen sondern nur bei ==0 break - also?!
MfG SideWinder
-
read == 0 -> Dateiende
read == -1 -> Fehler, errno könnte zB. EAGAIN sein.
-
Okay dann ist alles klar.
Danke nochmal für eure Hilfe!
MfG SideWinder