Next              Up                Back               Contents

Επόμενο:4.3 Παραλληλισμός Διασωλήνωσης Πάνω: Κεφάλαιο 4o : Επικοινωνία διεργασιών Πίσω: 4.1 Κανάλια Επικοινωνίας Διεργασιών


 

4.2 Μεταβλητές Καναλιών

Σε ορισμένες περιπτώσεις, κατά τη διάρκεια της επικοινωνίας των διεργασιών, είναι δυνατόν μια διεργασία να μην στείλει μόνο μια τιμή αλλά μια ολόκληρη σειρά από τιμές. Αυτός ο τύπος αλληλεπίδρασης ονομάζεται ορισμένες φορές και παραγωγός-καταναλωτής όπου η διεργασία παραγωγός υπολογίζει τιμές δεδομένων και τις στέλνει σε μια διεργασία καταναλωτή για περαιτέρω υπολογισμούς. Για να διευκολυνθεί αυτός ο γενικός τύπος τεχνικής του παράλληλου προγραμματισμού, η Multi-Pascal χρησιμοποιεί τις μεταβλητές καναλιών. Εννοιολογικά, το κανάλι συμπεριφέρεται σαν μια ουρά που περιέχει τιμές. Οι τιμές γράφονται στο κανάλι και αποθηκεύονται στην ουρά μέχρι να διαβαστούν από άλλες διεργασίες. Στο Σχήμα 4.2, το κανάλι C είναι σχεδιασμένο σαν ένας μακρύς σωλήνας ακριβώς για να φανεί αυτή η ιδιότητα. Καθώς οι τιμές γράφονται από τη διεργασία P1, εισέρχονται στο σωλήνα από τα αριστερά και ρέουν προς τα δεξιά όπου και διαβάζονται τελικά από τη διεργασία P2. Εάν η διεργασία P1 γράψει πολλές τιμές μέσα στο σωλήνα, αυτές αποθηκεύονται και μπορούν έπειτα να διαβαστούν ανά πάσα στιγμή από τη διεργασία P2.

 

 

4.2.1 Ανάγνωση και Εγγραφή Καναλιών

Μια τιμή μπορεί να γραφτεί σε μια μεταβλητή καναλιού με τον ίδιο τρόπο που γράφεται μια τιμή σε μια οποιαδήποτε άλλη μεταβλητή, το όνομα της μεταβλητής καναλιού χρησιμοποιείται στο αριστερό τμήμα μιας πρότασης ανάθεσης όπως φαίνεται και στο παρακάτω παράδειγμα για το κανάλι C:

 

image

ΣΧΗΜΑ 4.2 Επικοινωνία με τη χρήση της μεταβλητής καναλιού

C:=10;

Η παραπάνω πρόταση θα γράψει την τιμή 10 στο τέλος της εσωτερικής ουράς του καναλιού C. Φυσικά, το δεξιό τμήμα της ανάθεσης μπορεί να περιέχει οποιαδήποτε έγκυρη έκφραση της Pascal όπως για παράδειγμα φαίνεται παρακάτω:

C:=x+i*2;   (* Οι x και i είναι βαθμωτές μεταβλητές *)

Η παραπάνω πρόταση αφού υπολογίσει το γινόμενο δύο φορές το i και προσθέσει το x, γράφει την τιμή του αποτελέσματος στο κανάλι C. Οι μεταβλητές καναλιών δηλώνονται με κάποιο τύπο δεδομένων που καθορίζει το είδος των τιμών που αποθηκεύουν. Στην πρόταση ανάθεσης, η τιμή που υπολογίζεται από την έκφραση που υπάρχει στο δεξιό τμήμα πρέπει να ταιριάζει με τον τύπο δεδομένων του καναλιού με βάση τους ίδιους κανόνες που ισχύουν για τους τύπους μεταβλητών της κλασσικής Pascal. Ο τύπος δεδομένων της μεταβλητής καναλιού ορίζεται στο τμήμα δηλώσεων του προγράμματος μαζί με τις δηλώσεις και των υπολοίπων μεταβλητών. Η γενική σύνταξη για τη δήλωση μιας μεταβλητής καναλιού είναι η ακόλουθη:

< όνομα καναλιού >: CHANNEL OF < τύπος δεδομένων >;

Ο τύπος δεδομένων μπορεί να είναι οποιοσδήποτε τύπος μεταβλητής της κλασσικής Pascal όπως ακέραιες, πραγματικές, λογικές και μεταβλητές χαρακτήρων (INTEGER, REAL, BOOLEAN και CHAR). Επομένως μπορούμε να έχουμε κανάλια ακεραίων, πραγματικών, λογικών και μεταβλητών χαρακτήρων. Για να διαβάστε μια μεταβλητή καναλιού, χρησιμοποιείστε μόνο το όνομα του καναλιού στο αριστερό τμήμα μιας πρότασης ανάθεσης όπως φαίνεται και στο παρακάτω παράδειγμα:

x := C;

Η παραπάνω πρόταση ανάθεσης διαβάζει μια τιμή από την αρχή της ουράς τιμών που είναι αποθηκευμένη στο κανάλι C και την γράφει στην μεταβλητή x. Ο τύπος της μεταβλητής x πρέπει να ταιριάζει με τον τύπο συστατικού του καναλιού C. Για παράδειγμα, εάν το C είναι κανάλι πραγματικών αριθμών (CHANNEL OF REAL) τότε το x πρέπει να είναι πραγματική μεταβλητή (τύπου REAL). Κάθε εγγραφή στο κανάλι προσθέτει μια νέα τιμή στην εσωτερική ουρά ενώ κάθε ανάγνωση αφαιρεί μια τιμή από την εσωτερική ουρά.

Όταν μια διεργασία εκτελεί μια λειτουργία ανάγνωσης από ένα κανάλι που είναι άδειο τότε αυτομάτως η εκτέλεση της διεργασίας καθυστερεί μέχρι να γραφτεί μια τιμή στο κανάλι από κάποια άλλη διεργασία. Για παράδειγμα, εάν μια διεργασία αναγνώστης εκτελέσει την πρόταση x:=C ενώ το κανάλι είναι άδειο τότε η εκτέλεση αυτής της διεργασίας αναβάλλεται. Αργότερα όταν κάποια άλλη διεργασία γράψει τελικά μια τιμή στο κανάλι C τότε η διεργασία αναγνώστης αυτόματα συνεχίζει από το σημείο που σταμάτησε δηλαδή από την πρόταση x:=C. Αφού υπάρχει πλέον μια τιμή μέσα στο κανάλι C, μπορεί η πρόταση να εκτελεστεί επιτυχώς και η διεργασία αναγνώστης να συνεχίσει στην επόμενη πρόταση. Αυτή είναι μια από τις κύριες χρησιμότητες του καναλιού: έχει τη δυνατότητα να καθυστερεί τη διεργασία αναγνώστη μέχρι ότου η διεργασία συγγραφέας να τροφοδοτήσει τις απαιτούμενες τιμές. Κάθε κανάλι έχει απεριόριστη χωρητικότητα για την αποθήκευση οποιουδήποτε πλήθους τιμών και κατά αυτόν τον τρόπο οι διεργασίες συγγραφείς δεν καθυστερούν ποτέ.

Για να προσδιορίσουμε αν σε μια δεδομένη στιγμή ένα κανάλι περιέχει τιμές, μπορούμε να χρησιμοποιήσουμε μια λογική παράσταση με το όνομα του καναλιού συνοδευόμενο από το σύμβολο ?, όπως φαίνεται και στο επόμενο παράδειγμα του καναλιού C:

 

IF C?

    THEN x:=C (* Διαβάζει το κανάλι *)

    ELSE x:=0; (* Δεν διαβάζει το κανάλι *)

Η λογική παράσταση “C?” θα γίνει αληθής εάν εκείνη τη στιγμή το κανάλι C περιέχει τιμές ενώ θα γίνει ψευδής εφόσον το κανάλι είναι άδειο. Κάθε διεργασία μπορεί να ελέγξει αν η λογική παράσταση “C?” είναι αληθής ή ψευδής χωρίς τον κίνδυνο να καθυστερήσει. Η διεργασία που θα εκτελέσει την λειτουργία “C?” δεν θα αναβληθεί εάν το κανάλι είναι άδειο. Μια από τις πιο σημαντικές χρήσεις του ελέγχου του καναλιού είναι να βοηθήσει την διεργασία αναγνώστη να προσδιορίσει αν υπάρχει τίποτα μέσα στο κανάλι πριν εκτελέσει καμιά λειτουργία ανάγνωσης. Στο προηγούμενο παράδειγμα, η διεργασία ελέγχει πρώτα το κανάλι C και διαβάζει από αυτό μόνο αν περιέχει κάποια τιμή.

 

 

4.2.2 Παράδειγμα Παραγωγού-Καταναλωτή

 

Τα κανάλια είναι ιδιαίτερα χρήσιμα για το παράδειγμα του Παραγωγού-Καταναλωτή που χρησιμοποιείται συχνά για τον προγραμματισμό συστημάτων. Το παράδειγμα επεξηγείται στο Σχήμα 4.3 που δείχνει ένα τμήμα ενός προγράμματος που χρησιμοποιεί ένα κανάλι για την επικοινωνία τιμών ανάμεσα στις διεργασίες παραγωγού και καταναλωτή. Η διαδικασία Producer παράγει μια ακέραια τιμή με ορισμένους, άνευ σημασίας, εσωτερικούς υπολογισμούς και μετά γράφει την τιμή μέσα στο κανάλι commchan. Παρόμοια, η διαδικασία Consumer θα διαβάσει την τιμή από το κανάλι commchan και μετά θα την χρησιμοποιήσει σε δικούς της εσωτερικούς υπολογισμούς.

Η διεργασία παραγωγός θα συνεχίσει μέχρι να προκύψει μια ειδική τιμή τερματισμού endmarker (στην προκειμένη περίπτωση το -1). Η διεργασία καταναλωτής επίσης συνεχίζει το βρόχο και διαβάζει τις τιμές μέσα από το κανάλι μέχρι να ανιχνεύσει την τιμή τερματισμού. Το Σχήμα 4.4 επεξηγεί γραφικά τη γενική συμπεριφορά του προγράμματος Παραγωγού-Καταναλωτή. Η μεταβλητή καναλιού commchan χρησιμοποιείται ως μια ενδιάμεση μνήμη για τις τιμές που στέλνονται από τη διεργασία παραγωγού, στη διεργασία καταναλωτή. Αν ο παραγωγός είναι γρηγορότερος, τότε το κανάλι θα αποθηκεύσει τις επιπλέον τιμές μέχρι ο καταναλωτής να είναι σε θέση να τις χρησιμοποιήσει. Αν όμως ο καταναλωτής είναι πιο γρήγορος τότε θα βρει ορισμένες φορές το κανάλι άδειο. Όποτε συμβαίνει κάτι τέτοιο, το κανάλι θα αναγκάζει τον καταναλωτή να περιμένει μέχρι να γραφτεί κάποια τιμή στο κανάλι από τον παραγωγό. Παραδείγματα που υπάρχουν παρακάτω στο κεφάλαιο θα δείξουν πως η τεχνική του παραγωγού-καταναλωτή στον παράλληλο προγραμματισμό, μπορεί να χρησιμεύσει σε ορισμένα είδη εφαρμογών.

 

PROGRAM Producer_Consumer;

    CONST endmarker=-1;

    VAR commchan:CHANNEL OF INTEGER;

                    PROCEDURE Producer;

                    VAR inval:INTEGER;

                    BEGIN

                        REPEAT

                                ... (* Υπολογίζει το νέο αντικείμενο Inval για το κανάλι *)

                                commchan := inval; (* Γράφει μέσα στο κανάλι *)

                        UNTIL inval=endmarker;

                    END:

                    PROCEDURE Consumer;

                    VAR outval:INTEGER;

                    BEGIN

                        outval:=commchan; (* Διαβάζει από το κανάλι *)

                        WHILE outval<>endmarker DO

                            BEGIN

                              ... (* χρησιμοποίηση της outval σε ορισμένους υπολογισμούς *)

                              outval := commchan; (* Διαβάζει την επόμενη τιμή από το κανάλι*)

                            END;

         BEGIN (* Κυρίως πρόγραμμα *)

                FORK Producer; (* Διεργασία Producer *)

                FORK Consumer; (* Διεργασία Consumer *)

         END.

 

ΣΧΗΜΑ 4.3 Επικοινωνία παραγωγού-καταναλωτή με τη χρήση του καναλιού

image

ΣΧΗΜΑ 4.4 Αλληλεπίδραση του παραγωγού-καταναλωτή


     Next              Up                Back               Contents

Επόμενο: 4.3 Παραλληλισμός Διασωλήνωσης Πάνω: Κεφάλαιο 4o : Επικοινωνία διεργασιών Πίσω: 4.1 Κανάλια Επικοινωνίας Διεργασιών