Όπως ίσως να έχετε δει από παλιότερη ανάρτηση, έχει προταθεί η χρήση ενός νέου GIL (Global Interpreter Lock) στην Python 3.2. Μόλις χθες υποβλήθηκε ένα καινούργιο θέμα που προκύπτει με αυτόν τον GIL.
Επειδή ο χρόνος εκτέλεσης των I/O (Input/Output) λειτουργειών συνηθώς είναι αρκετά μεγάλος, όποτε αρχίζει μια τέτοια λειτουργία, ελευθερώνεται ο GIL ώστε να μπορούν να εκτελεστούν άλλα νήματα. Παρόλα αυτά υπάρχει ένας μεγάλος αριθμός από I/O λειτουργίες που εκτελούνται άμεσα, όπως για παράδειγμα η λειτουργία send() σε κάποιο socket όταν υπάρχει αρκετός χώρος στο buffer για να δεχθεί τα δεδομένα. Σε αυτές τις περιπτώσεις η απελευθέρωση του GIL για να εκτελεστεί κάποιο άλλο νήμα, επειδή περιμέναμε ότι η συγκεκριμένη λειτουργία θα έπαιρνε πολύ ώρα, είναι περιττή.
Ένα χαρακτηριστικό της καινούργιας υλοποίησης του GIL είναι ότι ο διερμηνευτής δεν ειδοποιεί περιοδικά τα νήματα που περιμένουν. Αντιθέτως, τα νήματα εναλλάσονται αφού περιμένουν ένα συγκεκριμένο χρονικό διάστημα. Αφού περάσει ένα συγκεκριμένο χρονικό διάστημα, ένα νήμα ειδοποιεί ότι θέλει τον GIL και τότε το νήμα που τον έχει μέχρι εκείνη την στιγμή υποχρεωούται να σταματήσει την λειτουργία του και να τον παραδώσει.
Αν και αυτή η ιδέα λύνει το πρόβλημα των νημάτων που είναι CPU-φραγμένα, εισάγει ένα καινούργιο πρόβλημα όταν αναμυγνείονται CPU-φραγμένα νήματα και I/O φραγμένα μαζί. Το πρόβλημα γίνεται εμφανές επειδή όταν το I/O φραγμένο νήμα εκτελεί μια I/O λειτουργία, απελευθερώνει πάντα τον GIL. Αφού ο GIL απελευθερώθηκε, ένα CPU φραγμένο νήμα είναι ελεύθερο να τον αποκτήσει και να τρέξει. Ωστόσο, αν η I/O λειτουργία σταματήσει αμέσως, τότε το I/O φραγμένο νήμα παγώνει μέχρι να επιστρέψει η κλήση συστήματος που αντιστοιχουσε την I/O λειτουργία. Για να πάρει το νήμα πίσω τον GIL, πρέπει να περιμένει αναγκαστικά να περάσει μια χρονική περίοδος, παρότι η λειτουργία του εκτελέστηκε σχεδόν ακαριαία.
Η ίδια συμπεριφορά παρουσιάζεται και στην Python 2, αλλά λόγω των μικρών χρονικών διαστημάτων στα οποία γίνεται ο έλεγχος, το I/O φραγμένο νήμα παίρνει πίσω τον GIL σχετικά γρήγορα.
Για περισσότερες λεπτομέρειες:
http://bugs.python.org/issue7946