Pipe zwischen 2 Funktionen - globale Pipe?
-
Hallo

Ich möchte gerne eine Pipe verwenden, aber nicht wie üblich zwischen 2 Prozessen (EP, KP) sondern zwischen zwei Funktionen.
In der Main Funktion wird ein Skript mit execl ausgeführt und das soll sein Input(stdin) von anderen Funktion holen, die sollen mit einer Pipe verbunden werden. stdin hab ich schon umgeleitet, alles kein Problem, ich frag mich nur, wie ich die Pipe nun genau anlegen soll.int fd[2]; pipe(fd);dieser Teil müsste dann ja global angelegt werden oder? Mir fällt es gerade nicht anders ein, aber wenn ich es so mache, passiert eigentlich nur Mist:
Zeile 10: Warnung: Parameternamen (ohne Typen) in Funktionsdeklaration
Zeile 10: Warnung: Datendefinition hat keinen Typ oder SpeicherklasseZeile 10 ist hierbei der befehl "pipe(fd)". Resultat ist eine endlosschleife von Bad-fds
Achja vorweg, nein es geht nicht zwischen zwei Prozessen, dass muss zwischen zwei Funktionen sein

-
Du musst die Funktion pipe() schon innerhalb einer Funktion absetzen. Idealerweise vor dem fork.
Nach dem fork, im Kindprozess, kannst Du dann fd[0] auf stdin dup'en (der Prozess liest dann aus der Pipe) und fd[1] schließen. Im Elternprozess schließt Du fd[0] und schreibst nach fd[1].
Wie das allerdings ohne Prozesse gehen soll, ist mir schleierhaft.
-
Kanns sein, dass ich eine unnamend Pipe verwende und diese nur mit verwandten Prozessen kommunizieren kann?
Also bräuchte ich entweder eine named Pipe (wie geht das in C?) oder ich muss mir was anderes einfallen lassen.
-
Ein merkwürdiges Design, möchte ich sagen. Wenn du die ganze Zeit im gleichen Prozess dich befindest, wozu soll eine Pipe gut sein? Genügt es nicht eine (globale) Variable? Sowas finde ich unnötige Ressourcen Verschwendung.
-
Vielleicht solltest Du das Ding mal genauer erklären. Eine Pipe ist für die Kommunikation zwischen zwei potentiell nebenläufigen Operationen. Zwei Funktionen sind aber erstmal nicht nebenläufig, Du errechnest normalerweise in der ersten Funktion einen Wert, rufst dann eine zweite Funktion auf und verarbeitest diesen.
EDIT:
In wiefern soll eine Named Pipe helfen? Eine Pipe ist und bleibt ein Ding wo man Daten reinschreibt, die auf der anderen Seite genauso wieder rauskommen.
-
Ich versuchs mal etwas genauer zu erklären
------------------- main() EP: // bestimmt den stdout vom KP/execl mittels Pipe // und verarbeitet ihn KP: // execl, stdout/stdin werden geschlossen. stdout geht an EP mittels Pipe // stdin soll von einer anderen Funktion kommen (geht ja nur mittels pipe?) -------------------hier dann die andere Funktion, von der der stdin kommen soll:
------------------- andereFunktion() //schreibt auf eine Pipe (sofern das geht) die direkt auf den stdin geleitet ist -------------------Wenn nicht mit einer Pipe, wie kann ich dann die Ausgabe der anderenFunktion() direkt auf den stdin vom EP leiten? dup2 will ja ein fd als Argument.
-
Noch ein Zusatz:
der EP ruft diese andere Funktion auf, somit ist sie dann ja doch ein paralleler Prozess und eine Pipe sinnvoll..
-
Also möchtest Du in main() einen Kindprozess erzeugen und erreichen, dass dieser Kindprozess Daten liest, die Du parallel zu dessen Ausführung in andereFunktion() (die nach dem Erzeugen des Kindprozesses in main() aufgerufen wird) in eine Pipe hineinschreibst?
Wie Du das erreichen kannst habe ich oben grob erläutert. Wo gibt es diesbezüglich Unklarheiten?
-
Bsp zu pipe (prozess 1: child, prozess 2: parent, oder andersrum
)#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char** argv) { int pfd[2]; pid_t cpid; char buf; assert(argc == 2); if(0 > pipe(pfd)){ perror("pipe failure"); exit(EXIT_FAILURE); } if(0 > (cpid = fork())){ perror("fork failed"); return EXIT_FAILURE; }else if(0 == cpid){ close(pfd[1]); while(0 < read(pfd[0], &buf, 1)){ write(STDOUT_FILENO, &buf, 1); } write(STDOUT_FILENO, "\n", 1); close(pfd[0]); exit(EXIT_SUCCESS); }else{ close(pfd[0]); write(pfd[1], argv[1], strlen(argv[1])); close(pfd[1]); wait(NULL); exit(EXIT_SUCCESS); } }Bsp zu popen (prozess 1: das hier, prozess 2: ls) :
#include <stdlib.h> #include <stdio.h> #include <string.h> #define LINE_SIZ 64 extern FILE* popen(const char*, const char*); extern int pclose(FILE*); int main(void) { char line[LINE_SIZ]; memset(line, '\0', LINE_SIZ); FILE *fp = popen("ls -l", "r"); while( fgets( line, sizeof(line), fp)){ printf("%s", line); } pclose(fp); exit(EXIT_SUCCESS); }Dann gaebs halt noch named pipes.. oder anderes - aber grundsaetzlich ist das alles IPC und nicht direkt Inter-funktions-kommunikation, sowas kann man auch per Parameter oder globaler Variablen erledigen. Oder nimmst Du Threads her, dann gehn die IPC Moeglichkeiten.
-
man: popen(3) wird bereits in stdio.h definiert. Du brauchst die Prototypen nicht nochmal per Hand zu schreiben.