Integer über Pipe übertragen
-
Hallo
Ich habe als Übung zum Auftrag bekommen, in C mittels Fork einen Prozess zu erzeugen und diesem über eine Pipe mehrere Integer zukommen zu lassen.
Nun habe ich aber das Problem, dass keine Werte ankommen. Ich bin seit Stunden am Rumtesten, habe wie wild gegoogelt, aber als Laie in Sachen C als auch Unix sehe ich wohl den Wald vor lauter Bäumen (write, fwrite, Files,...) nicht...
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <time.h> /* define preprocessor macros */ #define READ 0 #define WRITE 1 /** * main program */ int main(int argc, char **argv) { //Step 1... //step 2... /* ---------------------------- */ /* step 3: create pipe */ int thePipe[2]; pid_t pid; /* TODO pipe() and check whether is was successful */ if (pipe(thePipe) < 0) { perror ("Error @ Piping"); exit (EXIT_FAILURE); } /* ----------------------------- */ /* step 4: fork stuff & co */ pid = fork(); if (pid < (pid_t)0) { /* step 4.1: fork failed */ printf(stderr, "Fork failed.\n"); return EXIT_FAILURE; } if (pid == (pid_t)0) { /* step 4.2: code for child */ /* TODO close unnessary pipes and create local variables */ close(thePipe[WRITE]); /* TODO read int vales and perfrom the calculation */ /* use sleep(rand() % 5) for better readability on display */ int *a; a = malloc(sizeof(int)); read(thePipe[READ], *a, sizeof(int)); printf("Got a Number: %i\n", *a); /* TODO close pipes and exit */ close(thePipe[READ]); exit(0); } else { /* step 4.3: code for parent */ int array[]={19,9,17,15,4,12,6,3,4,136}; /* TODO close unnecessary pipes */ close(thePipe[READ]); /* TODO write actual int values to child */ int j; //for(j = 0; j < 10; j++) { write(thePipe[WRITE], array[j], sizeof(int)); //Write Test Value //} /* TODO close pipes */ close(thePipe[WRITE]); /* TODO wait for child and exit*/ wait(0); exit(0); } }
Das ist der Code, der mich zur Verzweiflung bringt. Ich versuche momentan, nur einen Integer aus Testzwecken zu übertragen. Ausgegeben wird aber immer 0.
Ich hoffe, ich habe mich verständlich ausgedrückt (ist ja schon spät) und bin natürlich dankbar für jede Art von Hilfe!
-
Statt
int *a; a = malloc(sizeof(int)); read(thePipe[READ], *a, sizeof(int)); printf("Got a Number: %i\n", *a);
dürfte
int a; read(thePipe[READ], &a, sizeof(int)); printf("Got a Number: %i\n", a);
gemeint sein. Außerdem ist hier
int j; //for(j = 0; j < 10; j++) { write(thePipe[WRITE], array[j], sizeof(int)); //Write Test Value //}
j nicht initialisiert und das Verhalten dementsprechend undefiniert.
Mehr sehe ich auf den ersten Blick nicht. Die Grundidee ist jedenfalls richtig.
-
Danke für die Antwort!
Leider funktioniert es immer noch nicht, in a werden beliebige Zahlwerte gespeichert, augenscheinlich Speicheradressen.
Ich habe auch versucht, einen String zu übertragen, das erste Zeichen auszulesen und in einem char zu speichern. Das funktioniert. Wenn ich aber einen einzelnen char (1 Byte) übertrage, dann wird der Wert gar nicht übernommen...
-
Sowohl write als auch read erwarten die Adresse eines buffers
int i = 123; write(thePipe[WRITE],&i,sizeof(int)); ... int i; read(thePipe[READ],&i,sizeof(int));
-
Mal auf das Wesentliche zusammengestrichen:
#include <unistd.h> #include <stdio.h> int main(void) { pid_t pid; int pipes[2]; pipe(pipes); pid = fork(); if(pid == 0) { /* Kindprozess */ int i = 123; close(pipes[0]); write(pipes[1], &i, sizeof(int)); close(pipes[1]); } else { /* Vaterprozess */ int i = 0; close(pipes[1]); read (pipes[0], &i, sizeof(int)); close(pipes[0]); printf("%d\n", i); wait(NULL); } return 0; }
Ich nehme an, dass deine Probleme mit Verwirrung um Arrays und Zeiger zu tun haben. Wo du einen String als
char str[] = "foo"; write(pipes[1], str, strlen(str) + 1);
übeträgst, muss es bei einem einzelnen Zeichen
char c = 'A'; write(pipes[1], &c, 1);
heißen, d.h., du musst die Adresse des Zeichens nehmen. read und write arbeiten auf rohem Speicher, also musst du einen Zeiger (genauer: void* bzw. void const*) auf das erzeugen, was du übertragen willst und die Anzahl der Bytes hinter dieser Stelle, die übertragen werden sollen. Bei Arrays macht der Compiler das automatisch, bei anderen Variablentypen musst du das von Hand machen.
-
Danke!!! Genau das war es!
Nun rechnet und zählt mein Prozess, wie er es soll.
-
Kruemelkatze schrieb:
Danke!!! Genau das war es!
Nun rechnet und zählt mein Prozess, wie er es soll.
Korrektur: Deine Prozesse.