digimyth Δημοσ. 18 Οκτωβρίου 2008 Δημοσ. 18 Οκτωβρίου 2008 Χαίρετε Βασικά θα ήθελα να μάθω πως δουλεύουν τα pipes στο linux για να μπορέσω να προγραμματίσω... Το μόνο που θέλω είναι έστω μια πηγή (βιβλίο, σελίδα, κτλ...) που να μπορώ να μάθω. Και ένα παράδειγμα χρήσης pipes σε C θα ήταν ευπρόσδεκτο. Thanks!
BadGuy Δημοσ. 18 Οκτωβρίου 2008 Δημοσ. 18 Οκτωβρίου 2008 Μπορείς να δεις εδώ μερικά παραδείγματα για να πάρεις μια ιδέα. http://www.linuxjournal.com/article/2156
pinball_elf Δημοσ. 18 Οκτωβρίου 2008 Δημοσ. 18 Οκτωβρίου 2008 Η σύνδεση που δώσατε είναι για pipes στο κέλυφος και όχι για προγραμμάτισμο. Πάντως η έννοια του pipe είναι η ίδια και στις δύο περιπτώσεις: δημιουργία ενός διαύλου (pipe) ενδοεπικοινωνίας μεταξύ δυο εφαρμογών. Στην C γίνεται με την popen: > #include <stdio.h> int main(void) { FILE * pipe_stream; char buf[512]; if ( ( pipe_strean = popen ("/usr/bin/ls", "r")) == NULL) /* open pipe with program 'ls' */ { fprintf (stderr, "popen error!\n"); } else { while (fgets(buf, 512, pipe_stream) != NULL) /* read pipe (output of program 'ls') */ fprintf(stdout,"%s", buf); pclose (pipe_stream); } return (0); } ΣΗΜΕΙΩΣΗ: Ο κώδικας δεν είμαι σίγουρος αν κάνει compile, γιατι δεν έχω έυκαιρο μηχάνημα με linux. Για περισσότερες πληροφορίες ψάξε για την popen.
digimyth Δημοσ. 21 Οκτωβρίου 2008 Μέλος Δημοσ. 21 Οκτωβρίου 2008 Βρήκα αυτό: > #include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> /* Read characters from the pipe and echo them to stdout. */ void read_from_pipe (int file) { FILE *stream; int c; stream = fdopen (file, "r"); while ((c = fgetc (stream)) != EOF) putchar (c); fclose (stream); } /* Write some random text to the pipe. */ void write_to_pipe (int file) { FILE *stream; stream = fdopen (file, "w"); fprintf (stream, "hello, world!\n"); fprintf (stream, "goodbye, world!\n"); fclose (stream); } int main (void) { pid_t pid; int mypipe[2]; /* Create the pipe. */ if (pipe (mypipe)) { fprintf (stderr, "Pipe failed.\n"); return EXIT_FAILURE; } /* Create the child process. */ pid = fork (); if (pid == (pid_t) 0) { /* This is the child process. Close other end first. */ close (mypipe[1]); read_from_pipe (mypipe[0]); return EXIT_SUCCESS; } else if (pid < (pid_t) 0) { /* The fork failed. */ fprintf (stderr, "Fork failed.\n"); return EXIT_FAILURE; } else { /* This is the parent process. Close other end first. */ close (mypipe[0]); write_to_pipe (mypipe[1]); return EXIT_SUCCESS; } } Αν και αδυνατώ να κατανοήσω πως όταν γράφεις στο mypipe[1] μετά το διαβάζεις από το mypipe[0] αλλά και για ποιο λόγο πρέπει να το κλείσεις!
pinball_elf Δημοσ. 21 Οκτωβρίου 2008 Δημοσ. 21 Οκτωβρίου 2008 Στο παράδειγμα που παρέθεσες χρησιμοποιείται η εντολή pipe η οποία στην ουσία δημιούργει δύο "αρχεία" (file descriptors) δυναμικά, στα οποία έχει πρόσβαση μόνο αυτός που την κάλεσε, και χρησιμοιποιείται για την ενδο-επικοινωνία μέσα στήν ίδια την εφαρμογή. Πιο συγκεκριμένα τα δεδομένα που γράφονται στον file descriptor mypipe[1] διαβάζονται από τον file descriptor mypipe[0]. Το παράδειγμα για να σου αποδείξει την χρησιμότητα της εντολής αυτής δημιουργεί μία επιπλέον διεργασία-παιδί (child process) με την εντολή fork, και χρησιμοποιεί την pipe για επικοινωνία μεταξύ διεργασία-πατέρα (parent process) και διεργασία-παιδί (child process). Μετά την fork η κάθε διεργασία κλείνει το άκρο της επικοινωνίας που δεν χρησιμοποιεί.
eirinikp Δημοσ. 21 Οκτωβρίου 2008 Δημοσ. 21 Οκτωβρίου 2008 Γεια, Εγώ έχω μία άλλη απορία: Θέλω να κοιτάζω σε ένα pipe αρχείο αν υπάρχει κάτι γραμμένο μέσα. Αν υπάρχει να το διαβάζω, ενώ αν δεν υπάρχει να προχωράω παρακάτω στο πρόγραμμά μου και να μην περιμένω. Από ότι έχω καταλάβει μέχρι τώρα, πρέπει να χρησιμοποιήσω την open και να βάλω flag O_NONBLOCK. Μετά κάνω read, αλλά φαίνεται σαν να μη διαβάζει τίποτα και μάλιστα η read μου επιστρέφει τιμή 0... Την είσοδο στο pipe την παιρνάω από ένα shell με την εντολή echo mplampla >> pipefile Καμία βοήθεια κανείς? Ευχαριστώ!
Επισκέπτης Δημοσ. 21 Οκτωβρίου 2008 Δημοσ. 21 Οκτωβρίου 2008 Γεια, Εγώ έχω μία άλλη απορία: Θέλω να κοιτάζω σε ένα pipe αρχείο αν υπάρχει κάτι γραμμένο μέσα. Αν υπάρχει να το διαβάζω, ενώ αν δεν υπάρχει να προχωράω παρακάτω στο πρόγραμμά μου και να μην περιμένω. Από ότι έχω καταλάβει μέχρι τώρα, πρέπει να χρησιμοποιήσω την open και να βάλω flag O_NONBLOCK. Μετά κάνω read, αλλά φαίνεται σαν να μη διαβάζει τίποτα και μάλιστα η read μου επιστρέφει τιμή 0... Την είσοδο στο pipe την παιρνάω από ένα shell με την εντολή echo mplampla << pipefile Καμία βοήθεια κανείς? Ευχαριστώ! θα πρέπει να χρησιμοποιήσεις συναρτήσεις όπως η select/poll/epoll κτλ. για να κάνεις poll όλα τα file descriptors. Ρίξε μια ματιά στο παρακάτω link, μπορεί να σε βοηθήσει http://www.lowtek.com/sockets/select.html
eirinikp Δημοσ. 21 Οκτωβρίου 2008 Δημοσ. 21 Οκτωβρίου 2008 θα πρέπει να χρησιμοποιήσεις συναρτήσεις όπως η select/poll/epoll κτλ. για να κάνεις poll όλα τα file descriptors. Ρίξε μια ματιά στο παρακάτω link, μπορεί να σε βοηθήσει http://www.lowtek.com/sockets/select.html Κάτσε, επειδή τα Αγγλικά μου δεν είναι και τόσο καλά και επειδή ούτε που την έχω ξαναακούσει αυτήν την poll, αν δε σου κάνει κόπο, μπορείς να μου εξηγήσεις τι κάνει αυτή η poll, για να καταλάβω τι με συμβουλεύεις να κάνω? Επίσης, τρόπος να διαβάσω ΑΠΛΑ από το pipe δεν υπάρχει? Ο κώδικάς μου είναι αυτός: > char *filename = //filepath tou pipe; int istream; ssize_t readcnt; char buffer[1]; sleep(4); //koimatai gia na prolabw na kanw echo sto pipefile istream = open (filename, O_RDONLY | O_NONBLOCK, "r"); readcnt = read(istream, buffer, (size_t)1); if (readcnt == -1) { printf("Error opening input pipe %s\n", filename); } else if( readcnt == 0 ) { printf( "to readcns itan 0\n" ); } else { printf( "diabasa: %s\n", buffer ); }
pinball_elf Δημοσ. 21 Οκτωβρίου 2008 Δημοσ. 21 Οκτωβρίου 2008 @eirinikp: έχεις ένα μικρό λάθος στον κώδικα σου: > istream = open (filename, O_RDONLY | O_NONBLOCK, "r"); readcnt = read(istream, buffer, (size_t)1); if (readcnt == -1) { printf("Error opening input pipe %s\n", filename); } else if( readcnt == 0 ) { printf( "to readcns itan 0\n" ); } else { printf( "diabasa: %s\n", buffer ); } θα πρέπει να είναι: > istream = open (filename, O_RDONLY | O_NONBLOCK, "r"); [color="Red"]if (istream == -1) { printf("Error opening input pipe %s\n", filename); } else { readcnt = read(istream, buffer, (size_t)1); if (readcnt == -1) { printf("Error reading input pipe %s\n", filename); } else if( readcnt == 0 ) { printf( "to readcns itan 0\n" ); } else { printf( "diabasa: %s\n", buffer ); }[/color] Αυτό που θέλεις να κάνεις στην ουσία δεν είναι να διαβάσεις ένα pipe, αλλά (echo mplampla << pipefile) να διαβάσεις από το stdin γιατί το "<<" δηλώνει ανακατεύθυνση των περιεχoμένων του αρχείου pipefile στο προγραμμα echo. Ένα pipe είναι το παρακάτω: "ls | sort".
eirinikp Δημοσ. 22 Οκτωβρίου 2008 Δημοσ. 22 Οκτωβρίου 2008 > istream = open (filename, O_RDONLY | O_NONBLOCK, "r"); [color="Red"]if (istream == -1) { printf("Error opening input pipe %s\n", filename); }[/color] Ευχαριστώ για τη διόρθωση αλλά το είχα υπόψην μου στο συνολικό πρόγραμμα, γιατί αμέσως πριν το ανοίξω είχα κάνει έλεγχο αν υπάρχει. Δεν έχει σημασία. Πάντως γενικά χθες δούλεψε οπότε όλα καλά! Ευχαριστώ και πάλι!
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.