• Save

Loading…

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Like this? Share it with your network

Share
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
388
On Slideshare
388
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

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