Πέμπτη, 19 Νοεμβρίου 2015

Σχέδιο Νημάτων (thread plan) και η αναθεώρηση 90

Στην αναθεώρηση 90 διόρθωσα ένα μικρό λαθάκι, και τώρα μπορεί να λειτουργήσει σωστά το παρακάτω παράδειγμα.

\\ Σχέδιο.νημάτων Διαδοχικό
Σχέδιο.νημάτων Ταυτόχρονο
Οθονη,0
Ανανέωση 3000
ι=0
Νήμα {
      Δρομέας 0,0
      Τύπωσε Πάνω $(4,8), ι, Γραφή$(τώρα,"hh:ss"),"Παράδειγμα με την Ανανέωση και Νήμα"
      Τύπωσε Υπο
      Ανανέωση
} Ως κ Κάθε 1000


Κύριο.Έργο 10 {


      Για ι=ι έως ι+100 {
            Θεση Τυχαίος(0,Χ.σημεία), Τυχαίος(0,Υ.σημεία)
            Χάραξε εως Τυχαίος(0,Χ.σημεία), Τυχαίος(0,Υ.σημεία), Τυχαίος(0,15)
            ι++
      }
      Αν Πατημένο(2) Τότε Έξοδος
      Αν Πατημένο(32) Τότε Έξοδος
}       
Νήματα Σβήσε




Το παράδειγμα βασίζεται στο προηγούμενο και θέλω να δείξω την διαφορά των δυο σχεδίων νημάτων. Την καταλαβαίνουμε οπτικά, από τις γραμμές που φαίνονται στην πάνω γραμμή όπου γράφουμε το τίτλο "Παράδειγμα...". 

Στο σχέδιο διαδοχικό, θα εκτελεστεί το νήημα Κ χωρίς να διακοπεί από το άλλο (το Κύριο.Έργο), άρα όταν θα τρέξει την "τύπωσε πάνω" θα σβήσει τυχόν γραμμές που έπεφταν στην πάνω γραμμή,  θα βάλει τα στοιχεία, θα βάλει την υπογράμιση με το "τύπωσε υπό"  και θα κάνει μετά ανανέωση της οθόνης. Έτσι αν πατήσουν αργότερα οι γραμμές το τίτλο εμείς δεν θα το δούμε!

Στο σχέδιο ταυτόχρονο ότι είναι σε αγκύλες θα εκτελεστούν χωρίς διακοπή. Στο νήμα Κ δεν έχουμε αγκύλες (αυτές που βλέπουμε όρισαν το νήμα, και στο κώδικα που αντιγράφεται στο νήμα  δεν υπάρχουν). Θα εκτελεστεί η "τύπωσε πάνω" αλλά μέχρι να εκτεστεί η ανανέωση, το πιθανότερο είναι ότι θα εκτελεστεί κάποιο από τα τρία κομμάτια του Κύριου Έργου και ίσως το Για { } που θα ρίξει εκατό γραμμές, και πιθανόν μερικές από αυτές να περνάνε από την γραμμή στο ύψος 0, (την πιο πάνω γραμμή χαρακτήρων στην οθόνη). Πράγματι θα δείτε να βγαίνουν γραμμές πάνω στο τίτλο!

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

{
      τύπωσε πάνω $(4,8), ι, γραφη$(τώρα,"hh:ss"),"Παράδειγμα με την Ανανέωση και Νήμα"
      τυπωσε υπο
      ανανεωση
}

Ο προγραμματισμός είναι ένα "παιχνίδι" διάγνωσης αλλαγής καταστάσεων και εδώ με την επιλογή ταυτόχρονο στο  σχέδιο.νημάτων μπερδεύονται τα πράγματα. Πάντως έχω και άλλα παραδείγματα πιο πολύπλοκα που φαίνεται η  καλή χρήση της "ταυτόχρονο " ή Thread.plan concurrent  (Thread.plan sequential το αντίστοιχο διαδοχικό). 

Μια παραλλαγή είναι με την χρήση της Για Επόμενο, η οποία όπως βλέπουμε δεν έχει μπλοκ που σημαίνει ότι μπορεί να εκτελεστεί με το σχέδιο ταυτόχρονο:
      για ι=ι εως ι+100
            θεση τυχαιος(0,χ.σημεια), τυχαιος(0,υ.σημεια)
            χαραξε εως τυχαιος(0,χ.σημεια), τυχαιος(0,υ.σημεια), τυχαιος(0,15)
            ι++
επόμενο ι

Η Για Εως Επόμενο είναι πιο αργή από την Για Εως {} αλλά μπήκε για δυο λόγους, για τη χρήση αυτή που μόλις περιέγραψα και επειδή μοιάζει με την ίδια εντολή της BASIC/ Υπάρχουν διαφορές με κύριες δύο ότι και να αλλάξουμε την τιμή στη μεταβλητή ελέγχου μέσα στην επανάληψη, αυτή δεν θα αλλάξει από την προγραμματισμένη για κάθε επανάληψη, που σημαίνει ότι στο επόμενο βήμα θα έχει την τιμή που πρέπει! Το δεύτερο είναι ότι το πρόσημο στο βήμα (μετά την εντολή ΑΝΑ, π.χ. Για Ι =1 έως 10 ανά 2  ) το τυχόν πρόσημο χρησιμεύει μόνο σε περίπτωση που η αρχή και το τέλος είναι ίδια, για να αποφασίσει ο διερμηνευτής τι τμή θα αφήσει μετά την επανάληψη. Ποτέ δεν αφήνει την ίδια τιμή με αυτή που ξεκινάει, και ποτέ δεν υπάρχει περίπτωση να μην εκτελέσει τουλάχιστον μια φορά την επανάληψη. (αυτά ισχύουν και για τις δυο ΓΙΑ). Στην Για { } βγαίνουμε πριν τελειώσουν όλες οι επαναλήψει με Έξοδος ή με ΠΡΟΣ μια ετικέτα εκτός μπλοκ, ενώ στην Για Επόμενο βγαίνουμε με την Έξοδος Για.

Η επόμενο μπορεί να υπάρχει περισσότερες από μια φορές. Δοκίμασε το παρακάτω. Δοκίμασε με ι<10 και με ι>10. Η έξοδος Για ή βρίσκει το τελευταίο Επόμενο ι αν δεν έχει γίνει μια πλήρη επανάληψη ή χρησιμοποιεί το τελευταίο επόμενο.ι. Αν αφαιρέσουμε την Προς 120 και βάλουμε Αν ι<10....τότε θα τυπωθεί το Οκ2, το 441, το Οκ και το 21. Αν βάλουμε το Προς 120 τότε θα δούμε το Οκ2 και το 21 μόνο. Η τελευταία Επόμενο ι δεν θα πειράξει το Ι, επειδή τελικά δεν πρόκειται να κάνει κάτι, η επανάληψη έχει τελειώσει, με την Έξοδος Για.

Για ι=1 Έως 100
Αν ι>20 τότε Έξοδος Για
\\Αν ι<10 τότε προς 100
Αν ι>10 τότε προς 100
Τύπωσε ι
Επόμενο ι
Τύπωσε "Οκ2"
Προς 120


100 Τύπωσε ι**2
110 Επόμενο ι
Τύπωσε "Οκ"
120
Τύπωσε ι

Μια αλλαγή που έκανα στην αναθεώρηση 90 είναι στη συνάρτηση Τυχαίος( ) να μην επαναρυθμίζει την γεννήτρια τυχαίων αλλά αν το θέλουμε τότε την καλούμε χωρίς παράμετρο και μας επιστρέφει το Αληθές (σε προηγούμενες αναθεωρήσεις θα δώσει λάθος, γιατί περιμένει παράμετρο τουλάχιστον μία αριθμητική έκφραση).

Μια επιπλέον αλλαγή είναι η "αποφόρτιση" του υπολογιστή κατά τη χρήση νημάτων με την εισαγωγή ανά 50 msec μιας εντολής sleep 1 όπου για δίνεται χρόνο στο σύστημα να κάνει ότι άλλη εργασία έχει να κάνει (ίσως πάρει περισσότερο χρόνο). Αν ανοίξουμε τον TaskManaget των Windows 7 θα δούμε την "κατανάλωση" ή φόρτο της CPU για την Μ2000. Αν δεν έχουμε νήματα να τρέχουν και δεν περιμένει το σύστημα να πληκτρολογήσουμε κάτι, τότε το περιβάλλον παίρνει το 100% του επεξεργαστή (αν έχουμε δύο τότε παίρνει το 50, αν έχουμε τέσσερις το 25, δηλαδή παίρνει έναν επεξεργαστή). Τα νήματα είναι κλήσεις από το Kernel σε ένα σύστημα "χώρου νημάτων σε αναμονή", απ΄όπου βγαίνει ένα νήμα, εξετάζεται αν θα τρέξει, και αν ναι μπαίνει σε ένα χώρο εκτέλεσης. Οπότε το σύστημα που εξετάζει αν κάτι θα εκτελεστεί δεν βρίσκει ποτέ αυτό που εκτελείται! Εκτός από τα νήματα που χρησιμοποιούμε για τα τμήματα υπάρχουν δυο τύποι ακόμα, που δουλεύουν ανεξάρτητα, και είναι τα νήματα μουσικής (οι δεκαέξι φωνές) και θα βρείτε εδώ ένα παράδειγμα  και οι σωληνώσεις, ο τρόπος να περνάμε δεδομένα από μια εφαρμογή της Μ2000 σε μια άλλη (για να φτιάχνουμε συστήματα Πελάτη Εξυπηρετητή, σε ένα τοπικό δίκτυο και όχι μόνο)

Μια προσθήκη ακόμα. Και εδώ παρουσιάζεται η τελική μορφή της εντολής Ανανέωση
Η αναθεώρηση 90 κλείνει το θέμα εδώ! 

\\ δεν μπορούμε να βάλουμε σημειώση στη γραμμή της θέσε
\\ η Θέσε στέλνει την γραμμή στον διερμηνευτή γραμμής
\\ εκεί δηλαδή που δίνουμε έξω από τμήματα εντολές
\\ η εντολή γρήγορα δεν ανήκει στις εντολές των τμημάτων
θέσε γρήγορα !
\\ θέσε γρήγορα
\\ θέσε αργά
ι=0
ανανέωση 200
{
      τυπωσε ι
       ανανέωση δοκιμή '' δεν χρειάζεται αν είμαστε σε ΑΡΓΑ ήγ ΓΡΗΓΟΡΑ, μόνο σε ΓΡΗΓΟΡΑ !
      \\ Επιλογές για ανανέωση
      \\ ανανέωση    - κάνει ανανέωση και μηδενίζει το μετρητή
      \\ ανανέωση 0 - μηδενίζει τον μετρητή  - άρα δίνει πρόσκαιρα χρόνο όσο το βήμα ανανέωσης
      \\ ανανέωση 100 - βάζει βήμα ανανέωησης τα 100 msec, και κάνει ανανέωση
      \\ Παρακάτω είναι το καινούργιο στην αναθεώρηση 90
      \\ ανανέωση δοκιμή  - κάνει ανανέωση αν είναι οκ ο μετρητής
      \\ Αυτό είναι χρήσιμο στο θέσε Γρήγορα ! όπου "αχρηστεύονται" οι δοκιμές για ταχύτητα
      \\ αλλά μπορούμε να βάλουμε μια εκεί που θέλουμε αντί για μια απλή ανανέωση
      \\ ώστε να μαζέψουμε αυτά που θέλουμε για ανανέωση.
      ι++
      Αν ι>1000 τότε έξοδος
      Κυκλικά
}




Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου