PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : problem mit pipes



pablo
04-05-2007, 22:08
ich moechte mit einer pipe folgendes machen:
parent prozess schreibt in pipe zahlen von 1 - 30, child proz gibt sie aus.
nun sollte das ganze aber doch nebenläufig ablaufen.
sprich parent schreibt zahl rein, und sofort liest sie der child prozess aus.

untenstehender code, sollte meines wissens eig. das umsetzen was ich beschrieben habe. Allerdings, und ich verstehs einfach nicht, werden zunaechst alle dreissig zahlen geschrieben, und dann - DANACH werden alle aus der pipe gelesen, aber nicht nebenläufig. Wieso?!

Und noch was: Was muss ich machen, wenn ich immer zehn werte in die pipe schreiben will. dann wieder 10 werte auslesen. Dann wieder zehn reinschreiben, wieder zehn auslesen...?

besten dank.





#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <wait.h>






int main(){

pid_t pid;
int status;

int last_value=0;
int i=0;

int fd[2];
int read_bytes,sent_bytes=0;
FILE *schreib;
FILE *les;
int input;


//richte eine pipe ein,
//hier nur eine pipe noetig, da kommunikation nur in eine richtung
//pipe braucht keine Sync!
if (pipe(fd) < 0)
puts("kann keine pipe einrichten!!");

switch ( pid = fork() )
{
case -1:
{
printf("error with fork()\n");
break;
}

case 0:
//child
{
printf("Kindprozess == Leseprozess laeuft!\n\n");
//child liest nur aus pipe
close(fd[1]);

if ( ( les = fdopen(fd[0], "r")) == NULL)
puts("Fehler in fdopen - lesen in child");

//liest solange bis EOF erscheint, das kommt wenn pipe von anderer seite geschl. wird
while(fscanf(les,"%d", &input) != EOF)
printf("lese %d \n", input);



_exit(0);

break;
}

default:
//parent
{
printf("Elternprozess == Schreibprozess laeuft!\n");

//parent schreibt nur in pipe
close(fd[0]);

if ( (schreib = fdopen(fd[1], "w")) == NULL)
puts("fehler in fdopen bei schreib-fd!");


while(1)
{
for(i=0; i<10; i++){
last_value++;
//schreibt einfach angegebene menge an bytes in die pipe(formatiert ueber schreib)
fprintf(schreib, "%d ", last_value);

printf("schreibe...%d \n", last_value);
}

if (last_value == 30)
{
printf("alle zahlen geschrieben! ende. . warte auf child.\n");

//pipe schliessen, child merkt fertig mit schreiben
fclose(schreib);

//auf child warten!
wait(&status);
_exit(0);
}
}

break;
}

}

return -1;
}

nul
05-05-2007, 00:09
Wie waerst wenn du Vater und Kind synchronisierst, das loest all deine Probleme so wie ichs verstehe!

pablo
05-05-2007, 08:32
aber ich dachte pipes kommen ohne synchronisation aus?
das unterscheidet sie doch gerade von shared memory?

locus vivendi
05-05-2007, 10:11
untenstehender code, sollte meines wissens eig. das umsetzen was ich beschrieben habe. Allerdings, und ich verstehs einfach nicht, werden zunaechst alle dreissig zahlen geschrieben, und dann - DANACH werden alle aus der pipe gelesen, aber nicht nebenläufig. Wieso?!
Woher weißt du, dass zwangsläufig erst aller Zahlen geschrieben werden und dann vom Kind gelesen? Es könnte doch, von vorneherein betrachtet, so sein, dass du nur nicht genügend Programmläufe getestet hast um eine anderes Verhalten zu beobachten.

Zweitens, die C-Bibliothek darf durchaus Daten puffern, bevor sie an das Betriebssystem weitergegeben werden. Das könnte für dich eine Rolle spielen.

Drittens, weshalb interessiert dich das überhaupt? Du erzeugst doch geraden einen zweiten Prozess damit er vom ersten *entkoppelt* läuft. Wenn du eine Reihenfolge haben möchtest "Schreiben 1, Lesen 1, Schreiben 2, Lesen 2, Schreiben 3, ..." dann verzichte auf das Forken.

Noch eine persönliche Anmerkung zu deiner Methode, zig Variablen an den Anfang der Funktion zu knallen obwohl sie dort noch gar nicht gebraucht werden: Das erschwert Leuten die dir Helfen wollen das Lesen deines Codes. Deshalb wäre es wohl besser, beim nächsten mal die Variablen erst dort zu definieren, wo sie verwendet werden.

locus vivendi
05-05-2007, 10:13
aber ich dachte pipes kommen ohne synchronisation aus?
Pipes kann man zum Synchronisieren von Prozessen benutzen, indem zum Beispiel eine Ende blockieren liest und darauf wartet, das auf der anderen Seite etwas geschrieben wird.