www.mikrocontroller.net

Forum: PC-Programmierung Linux fifo blockierend lesen


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

ich habe mit mknod name p einen fifo angelegt. Ich kann diesen auch mit 
fopen öffnen und mit fread bzw. read lesen. Die Leseoperation blockiert 
auch ein mal.

Sobald ich aber einmal etwas in den Fifo reinpipe, wird die blockierung 
dauerhaft aufgehoben. Eigentlich sollte doch der Inhalt nur einmal 
auslesbar sein. Der Inhalt wurde also nicht "gelöscht". Wie muss ich das 
jetzt lösen? Gibt es ein fpops?

Autor: Rolf Magnus (rmagnus)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Helmert schrieb:
> Hallo,
>
> ich habe mit mknod name p einen fifo angelegt. Ich kann diesen auch mit
> fopen öffnen und mit fread bzw. read lesen. Die Leseoperation blockiert
> auch ein mal.
>
> Sobald ich aber einmal etwas in den Fifo reinpipe, wird die blockierung
> dauerhaft aufgehoben.

Wie das? Was passiert denn, wenn du nichts mehr reinsteckst?

> Eigentlich sollte doch der Inhalt nur einmal auslesbar sein.

Ja. Kommt bei dir denn irgendwas mehrfach?

> Der Inhalt wurde also nicht "gelöscht".

Wurde er nicht?

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Ja. Kommt bei dir denn irgendwas mehrfach?

Ja, der gesamte Inhalt. Es geht immer wieder ganz von vorne los. Mit 
jeder fread-Operation liest er er den gesamten Inhalt wieder von vorne.

Autor: Rolf Magnus (rmagnus)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Dann machst du wohl irgendwas falsch, denn das ist nicht das normale 
Verhalten. Mehr läßt sich jetzt mit den Informationen kaum sagen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Wahrscheinlich scheitert das Lesen, aber er ignoriert den Fehler?

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Das jedenfalls läuft wie ich es erwarten würde:
/* Time-stamp: "22.03.12 20:17 lese.c klaus?wachtler.de"
 *
 */

#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

int main( int nargs, char **args )
{
  char c;
  int     fd = open( "/tmp/a", O_RDONLY );
  if( fd==-1 )
  {
    perror( "war nix mit oeffnen" );
    exit( 1 );
  }

  while( 1==read( fd, &c, 1 ) )
  {
    printf( "gelesen: %c %3d\n", ( isprint(c) ? c : '?' ), c );
  }
  perror( "Fehler beim Lesen" );
  close( fd );

  return 0;
}

/* Time-stamp: "22.03.12 20:10 schreibe.c klaus?wachtler.de"
 *
 */

#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main( int nargs, char **args )
{
  int     fd = open( "/tmp/a", O_WRONLY );
  if( fd==-1 )
  {
    perror( "war nix mit oeffnen" );
    exit( 1 );
  }

  write( fd, "hallo\n", 6 );
  close( fd );

  return 0;
}

Ausgabe beim Lesen:
klaus@vdr2:~ > ./lese
gelesen: h 104
gelesen: a  97
gelesen: l 108
gelesen: l 108
gelesen: o 111
gelesen: ?  10
Fehler beim Lesen: Success

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Also ich mach das so:
#include <stdio.h>
#include <iostream>
//#include <fstream>

int main(void)
{
FILE* node;
char text[512];
size_t chrs;


node = fopen("filter","rb");


while(1){
        chrs = fread(text,1,512,node);
        printf(text);
}


return 0;
}



Da müsste doch das fread immer wieder anhalten, bis wieder was in den 
Fifo.

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
nein, das fread scheitert, du merkst es aber nicht und gibst immer 
wieder das aus, was vom ersten Lesen noch im Puffer steht.
Ändere doch mal den Puffer nach dem ersten Lesen, und du wirst sehen, 
daß beim zweiten Lesen nicht mehr der alte Inhalt wieder gelesen wird.

Man könnte auch mal den Rückgabewert vom fread anschauen...

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ja, das zweite Lesen schlägt fehl, soll es aber nicht. Es soll erneut 
blockieren statt fehlschlagen.

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
genau genommen schlägt es ja auch nicht fehl, sondern liefert 
erfolgreich 0 Zeichen :-)

Du wirst schon den Rückgabewert deiner Funktion anschauen müssen.

Evtl. kann man beim direkten Lesen mit read etwas drehen, aber bei fread 
fällt mir nichts ein.

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ja, so wie es aussieht, muss nach dem ersten Lesen die Datei/Fifo 
geschlossen und wieder geöffnet werden...

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Warum nimmst du überhaupt die Streamfunktionen, wenn du eh Blöcke lesen 
willst?
Mit den low level-Funktionen hat man z.B. select zum Testen, ob etwas da 
ist.

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
So, der Code, den ich schon gepostet habe, funktioniert jetzt. Ich hatte 
einige geändert und nun wieder diesen ursprünglichen Zustand 
hergestellt. Ich glaube der Compiler hat sich jetzt an meinem 
"Programmierstil" gewöhnt.

Autor: Klaus Wachtler (mfgkw)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ja, bestimmt

Autor: Rolf Magnus (rmagnus)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Klaus Wachtler schrieb:
> genau genommen schlägt es ja auch nicht fehl, sondern liefert
> erfolgreich 0 Zeichen :-)

Es liefert dann 0, wenn man am Ende des Files angekommen ist und dann 
nochmal versucht zu lesen. Das Fileende kommt bei einem FIFO dann, wenn 
die Gegenseite ihn schließt.

> Du wirst schon den Rückgabewert deiner Funktion anschauen müssen.
>
> Evtl. kann man beim direkten Lesen mit read etwas drehen, aber bei fread
> fällt mir nichts ein.

Man könnte feof() verwenden, aber das wäre unsinnig, nur um sich das 
Auswerten des Rückgabewerts von fread() zu sparen.

Stefan Helmert schrieb:
> Ja, das zweite Lesen schlägt fehl, soll es aber nicht. Es soll erneut
> blockieren statt fehlschlagen.

Fehlschlagen tut es nur dann, wenn ein Fehler aufgetreten ist oder die 
Gegenseite den FIFO geschlossen hat. Praktischerweise kann man sich eine 
textuelle Beschreibung des Fehlers mit perror() ausgeben lassen.

Autor: DwIm (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Helmert schrieb:
> Ich glaube der Compiler hat sich jetzt an meinem
> "Programmierstil" gewöhnt.

Ich installiere in solchen Fällen immer den DwIm Compiler.

DwIm = Do what I mean.

Autor: Stefan Helmert (Firma: dm2sh) (stefan_helmert)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Kann es sein, dass nicht das fread blockiert, sondern das fopen?

Autor: Andreas B. (andreas_b77)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Helmert schrieb:
> Kann es sein, dass nicht das fread blockiert, sondern das fopen?

Ja, falls das FIFO noch keine Gegenstelle hat und im blockierenden Modus 
geöffnet wird, was mit stdio-Funktionen sowieso nicht anders möglich 
ist.

Das alles ist dokumentiert: "man fifo" und "man 7 pipe".

Autor: tamptus (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Stefan Helmert schrieb:
> chrs = fread(text,1,512,node);
>         printf(text);

Das bitte nie so machen.
immer:

chrs = fread(text,1,512,node);
          printf("%s",text);

siehe auch hier: http://en.wikipedia.org/wiki/Format_string_attack

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net