ΛΣ2IPCv0

379 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
379
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

ΛΣ2IPCv0

  1. 1. IPC Γ.Μανάρας 1
  2. 2.  Τρόποι επικοινωνίας διεργασιών  Pipes  FIFOs 2
  3. 3.  Στο ίδιο μηχάνημα: Pipes, σήματα, μηνύματα, global memory, αρχεία  Σε διαφορετικά μηχανήματα Named pipes (FIFOs) sockets IIOP (CORBA, OO wrappers για sockets) COM+(Win32) Mail-slots(Win32) Web Services 3
  4. 4.  Ανοίξτε ένα x-terminal και τρέξτε την εντολή $ ls –l | wc –l Τι θα συμβεί?  Στο Α’ μέρος του σημερινού μαθήματος θα εξηγήσουμε πως ακριβώς υλοποιούνται όλα αυτά σε επίπεδο λειτουργικού συστήματος  Pipe: ειδικός τύπος αρχείου FIFO που χρησιμοποιείται για την σειριακή μεταφορά δεδομένων μεταξύ δύο διεργασιών, προς μια κατεύθυνση  Μπορεί να είναι είτε μόνιμο (δηλαδή με όνομα) είτε προσωρινό 4
  5. 5. 5
  6. 6.  int pipe(int fd[]);  Η κλήση pipe() λαμβάνει ως παράμετρο ένα array fd δύο ακεραίων και επιστρέφει δύο file descriptors  Το fd[0] READ , προσδιορίζει το άκρο του pipe από όπου διαβάζουμε  Το fd[1] WRITE, προσδιορίζει το άκρο στο οποίο γράφουμε  Τα στοιχεία που γράφονται στο ένα άκρο της σωλήνωσης μπορούν να διαβαστούν από το άλλο.  Τα μη χρησιμοποιούμενα άκρα πρέπει να ελευθερώνονται με την close().  Το pipe() επιστρέφει 0 σε επιτυχία ή -1 σε αποτυχία. 6
  7. 7.  Παράδειγμα 1: pipe1.c #include <stdio.h> main() { int fd[2], n; char message[100]; pipe(fd); write(fd[1], "This is a pipe message", 22); n = read(fd[0], message, 100); /* write the message to stdout */ write(1, message, n); }  Η εκτέλεση του προγράμματος θα μας δώσει: This is a pipe message 7
  8. 8.  Η function perror(const char * str)  Μερικές C functions, όταν συμβεί κάποιο λάθος, θέτουν μία τιμή στη global var errno.  Η δουλειά της perror() είναι να εμφανίσει - το αλφαριθμητικό str που της περάσαμε καθώς και - το μήνυμα που αντιστοιχεί στην τιμή που έχει η errno.  Παράδειγμα  FILE * pFile = fopen ("unexist.ent","rb"); if (pFile==NULL) perror ("The following error occurred"); else fclose (pFile);  Τελικά θα εμφανιστεί: «The following error occurred: No such file or directory» Η βασική χρησιμότητα του δικού μας μηνύματος είναι να μας βοηθάει να εντοπίσουμε το σημείο του κώδικα που έγινε το λάθος. 8
  9. 9.  Παράδειγμα 2: pipe2.c #include <stdio.h> char *line = "This is an IPC message, with pipe"; main() { int pid, fd[2], n; char message[100]; if (pipe(fd) == -1) { perror("pipe"); exit(1); } pid = fork(); if ( pid == -1) { perror("fork"); exit(2); } 9
  10. 10. if (pid == 0) { /* Child process is the writer */ close(fd[0]); write(fd[1], line, strlen(line)+1); close(fd[1]); } else { /* Parent process is the reader */ close(fd[1]); n = read(fd[0], message, sizeof(message)); write(1, message, n); // write the message to the stdout close(fd[0]); } }  Η εκτέλεση του προγράμματος θα μας δώσει:  This is an IPC message, with pipe 10
  11. 11.  H function int dup2(int fildes, int fildes2);  Κάνει το fildes alias του fildes2  Παράδειγμα Αν θέλουμε να κατευθύνουμε το standard output σε ένα αρχείο int file = open("myfile.txt", O_APPEND | O_WRONLY); if(file < 0) return 1; //Now we redirect standard output to the file using dup2 if(dup2(file,1) < 0) return 1; //Now standard out has been redirected, we can write to the file printf("This will be printed in myfile.txt“); 11
  12. 12. Παράδειγμα 3: pipe3.c #include <stdio.h> main() { int fd[2], pid; char message[100]; if (pipe(fd) == -1) { /* Create a pipe */ perror("pipe"); exit(1); } if ((pid = fork()) == -1) { /* Fork a child */ perror("fork"); exit(2); } 12
  13. 13. if (pid == 0) { /* Child process is the reader */ close(fd[1]); dup2(fd[0],0); /* stdin becomes fd[0] */ close(fd[0]); printf("I am the child…n"); scanf("%s",message); printf("From parent: %sn", message); scanf("%s", message); printf("From parent: %sn", message); scanf("%s", message); printf("From parent: %sn", message); exit(0); } else { /* Parent process is the writer */ close(fd[0]); dup2(fd[1],1); /* stdout becomes fd[1] */ close(fd[1]); printf("Hello my childn"); } } 13
  14. 14.  Παράδειγμα 4: pipe4.c #include <stdio.h> main() { int fd[2], pid; char *argv[3]; if (pipe(fd) == -1) { /* Create a pipe */ perror("pipe"); exit(1); } if ((pid = fork()) == -1) { /* Fork a child */ perror("fork"); exit(2); } 14
  15. 15. if (pid == 0) { /* Child process is the reader */ close(fd[1]); /* Close the writing side */ dup2(fd[0],0); /* stdin becomes fd[0] */ close(fd[0]); /* now, close the fd[0] */ execlp("wc", "wc" , NULL); perror("execlp"); } else { /* Parent process is the writer */ close(fd[0]); /* Close the reading side */ dup2(fd[1],1); /* stdout becomes fd[1] */ close(fd[1]); /* now, close the fd[1] */ argv[0] = "ls"; argv[1] = "-l"; argv[2] = NULL; execvp("ls", argv); perror("execvp"); } } 15
  16. 16.  Με τη χρήση των FIFO μπορούν να ανταλλάξουν δεδομένα και διεργασίες που δεν έχουν «συγγενική» σχέση μεταξύ τους  Η κλήση συστήματος mkfifo() δημιουργεί έναν επώνυμο σωλήνα που έχει τις ίδιες ιδιότητες με έναν ανώνυμο σωλήνα (half-duplex, fist in – first out), με τη διαφορά ότι στην ουσία πρόκειται για ένα αρχείο στο δίσκο  int mkfifo(const char *path, mode_t mode); 16
  17. 17.  Παράδειγμα 5: fifo1.c main() { int fd, n; char buff[100], msg[]="Text for FIFO"; unlink("FIFO"); /* remove, if exist */ if (mkfifo("FIFO", 0764) == -1) { perror("mkfifo"); exit(1); } if ((fd=open("FIFO", O_RDWR)) == -1) { perror("open"); exit(2); } n=write(fd,msg,strlen(msg)); if (read(fd, buff, n)==-1) fprintf(stderr,"Can't read from Fifo.n"); else printf("Read from FIFO: %sn", buff); } 17
  18. 18.  Παράδειγμα 6: receiver.c int main() { int fd; char buffer[100]; unlink("FIFO"); if (mkfifo("FIFO", 0755) == -1) { fprintf(stderr,"Receiver: Coudn't create fifo.n"); exit(2); } if ((fd = open("FIFO", O_RDWR)) == -1) { fprintf(stderr, "Receiver: fifo open failed.n"); exit(1); } 18
  19. 19.  Παράδειγμα 6: receiver.c while(1) { if (read(fd, buffer, 100) == -1) { fprintf(stderr,"Receiver: fifo reading failed.n"); exit(2); } printf("Received message: %sn", buffer); if (!strcmp(buffer,"exit")) exit(0); } return 0; } 19
  20. 20.  Παράδειγμα 6: sender.c int main(int argc, char *argv[]) { int fd, i, n; char buffer[100]; if (argc < 2) { fprintf(stderr, "Usage: %s message ...n", argv[0]); exit(1); } if ((fd = open("FIFO", O_RDWR | O_NONBLOCK)) == -1) { fprintf(stderr, "Sender: fifo open failed.n"); exit(3); } 20
  21. 21.  Παράδειγμα 6: sender.c for (i = 1; i < argc; i++) { strcpy(buffer, argv[i]); if ((n = write(fd, buffer, 100)) == -1) { fprintf(stderr, "Sender: Write to fifo failed.n"); exit(4); } } return 0; } 21

×