22. Η λύση του προβλήματος παραγωγού/καταναλωτή με σεμαφόρους

                Το πρόβλημα του παραγωγού/καταναλωτή είναι ένα κλασικό πρόβλημα συγχρονισμού. Οι διεργασίες παραγωγού και καταναλωτή μοιράζονται ένα κοινό  Buffer (με οκτώ θέσεις (slots) στο παράδειγμα αυτό). Ο παραγωγός εκτελεί ένα άπειρο βρόχο, στον οποίο θέτει νέα αντικείμενα στο buffer και ο καταναλωτής εκτελεί ένα άπειρο βρόχο κατά τον οποίο καταργεί αντικείμενα από το buffer. Οι ακόλουθες σημαντικές προϋποθέσεις πρέπει να πληρούνται από τον παραγωγό και καταναλωτή:

 

·         Το πολύ μία διεργασία (παραγωγός ή ο καταναλωτής) μπορεί να έχει πρόσβαση το κοινό buffer ανά πάσα στιγμή. Αυτή η κατάσταση ονομάζεται αμοιβαίος αποκλεισμός.

·         Όταν o Buffer είναι πλήρης (έχουν ληφθεί και τα οκτώ slots), ο παραγωγός θα πρέπει να τεθούν σε κατάσταση sleep. Θα πρέπει να ξυπνήσει όταν ένα άδειο slot γίνει διαθέσιμο. Αυτό ονομάζεται συγχρονισμός.

·         Όταν το buffer είναι άδειο, ο καταναλωτής θα πρέπει να τεθεί σε κατάσταση sleep. Θα πρέπει μόνο να ξυπνήσει όταν γεμίσει ένα slot. Αυτή η διαδικασία ονομάζεται επίσης συγχρονισμός.

Αυτός ο προσομοιωτής εμφανίζει μια λύση στο πρόβλημα του καταναλωτή-παραγωγού με τρεις σεμαφόρους: mutex, full, και empty.

·         O Mutex είναι ένα δυαδικόw σεμαφόρος που ελέγχει την πρόσβαση στον κοινόχρηστο buffer. Εγγυάται αμοιβαίο αποκλεισμό για το buffer.

·         Ο full  είναι ένα σεμαφόρος μετρητής που μετράει τον αριθμό των πλήρων slots.

·         Ο empty είναι ένα σηματοφόρος μετρητής που μετράει τον αριθμό των κενών slots.

Ο προσομοιωτής δείχνει τον κωδικό για τον παραγωγό και τη διαδικασία των καταναλωτών καθώς και τον κοινό buffer. Μπορείτε να εκτελέσετε τον προσομοιωτή σε μια κατάσταση βήμα προς βήμα πατώντας το κουμπί STEP κάτω από κάθε διεργασία. Αυτό θα προωθήσει τη διαδικασία με βάση  τον κώδικά της. Μπορείτε να δείτε πώς το περιεχόμενο του buffer και η τιμή των σεμαφόρων αλλάζουν, ως αποτέλεσμα της εκτέλεσης της διεργασίας. Ένα παράθυρο κάτω από κάθε διαδικασία υποδηλώνει αν η διαδικασία βρίσκεται σε λειτουργία ή «κοιμάται» περιμένοντας ένα συγκεκριμένο σεμαφόρο. Μπορείτε επίσης να εκτελέσετε τον προσομοιωτή σε μια κατάσταση animation πατώντας το κουμπί ANIMATE. Θα δείτε τους ελέγχους που σας επιτρέπουν να αλλάξετε τη ταχύτητα εκτέλεσης και τον χρόνο που απαιτείται για έναν παραγωγό να παράγει ένα στοιχείο και για έναν καταναλωτή να καταναλώσει ένα στοιχείο.