# Γρήγορη εκκίνηση: ο δαίμονας Κάθε κλήση του `pperl` πληρώνει κανονικά το πλήρες κόστος της εκκίνησης: δημιουργία διεργασίας, αρχικοποίηση του διερμηνέα και - το ακριβό μέρος για τα πραγματικά προγράμματα - μεταγλώττιση του σεναρίου σας και κάθε αρθρώματος που εισάγει με `use`. Ο δαίμονας επιτρέπει σε επαναλαμβανόμενες κλήσεις του ίδιου σεναρίου να παρακάμπτουν αυτό το κόστος: μια μόνιμη διεργασία κρατά μια πλήρως μεταγλωττισμένη εικόνα του σεναρίου, και κάθε νέα εκτέλεση είναι ένα fork αυτής της εικόνας που περνά κατευθείαν στην εκτέλεση. Το χαρακτηριστικό είναι αυστηρά **opt-in**, ανά κλήση. Τίποτα δεν αλλάζει για ένα απλό `pperl script.pl`, και όποτε ο δαίμονας δεν μπορεί να εξυπηρετήσει ένα αίτημα ακριβώς, το pperl καταφεύγει σιωπηλά σε μια κανονική ψυχρή εκτέλεση. Η ορθότητα δεν εξαρτάται ποτέ από τον δαίμονα· μόνο η ταχύτητα εξαρτάται. ## Γρήγορο ξεκίνημα ```bash pperl --daemon=start # start the daemon (background) PPERL_DAEMON=2 pperl report.pl # first run: compiles, caches PPERL_DAEMON=2 pperl report.pl # every further run: fork + run pperl --daemon=status # what is cached, what is live pperl --daemon=stop # shut it down ``` Η πρώτη opt-in εκτέλεση ενός σεναρίου χτίζει το *πρότυπό* του: ο δαίμονας μεταγλωττίζει το σενάριο (συμπεριλαμβανομένων όλων των αρθρωμάτων που εισάγονται με `use` και των μπλοκ `BEGIN`) και κρατά το αποτέλεσμα μόνιμο. Κάθε μεταγενέστερη εκτέλεση του ίδιου σεναρίου κάνει fork το πρότυπο και απλώς εκτελεί. ## Πότε αποδίδει Η εξοικονόμηση είναι ο χρόνος μεταγλώττισης του σεναρίου σας: η ανάλυση, συν η φόρτωση αρθρωμάτων, συν η εργασία στο `BEGIN`. Για ένα σενάριο που φορτώνει μια χούφτα αρθρώματα, αυτό είναι συνήθως το κυρίαρχο μέρος της εκκίνησης, και μια εκτέλεση από πρότυπο μπορεί να είναι πολλαπλάσια ταχύτερη από άκρη σε άκρη. Για ένα ασήμαντο σενάριο που δεν φορτώνει τίποτα, η εξοικονόμηση ισούται περίπου με το ίδιο το overhead του δαίμονα και το αποτέλεσμα είναι ισοπαλία - ποτέ ουσιαστική απώλεια. Όπως παντού σε αυτόν τον οδηγό: μετρήστε το δικό σας σενάριο, στο δικό σας μηχάνημα, πριν βγάλετε συμπεράσματα - δείτε [Μέτρηση](measuring.md). ## Τι σημαίνει η εκτέλεση από πρότυπο Μια εκτέλεση από πρότυπο εκτελεί μόνο τη *φάση εκτέλεσης* του σεναρίου σας. Η μεταγλώττιση έγινε ήδη, μία φορά, όταν χτίστηκε το πρότυπο. Το pperl εγγυάται ότι τα ακόλουθα είναι φρέσκα και ορθά για κάθε εκτέλεση: - `@ARGV`, `%ENV`, ο τρέχων κατάλογος, umask - η τυπική είσοδος, έξοδος και σφάλμα (οι ανακατευθύνσεις και οι σωληνώσεις σας) - το id της διεργασίας `$$` - οι κωδικοί εξόδου και ο θάνατος από σήμα (ένα σκοτωμένο σενάριο σκοτώνει το `pperl` που το κάλεσε με τον ίδιο τρόπο) - ο χειριστής `__DATA__` - κάθε εκτέλεση τον διαβάζει από την αρχή, ανεξάρτητα από τις άλλες εκτελέσεις Αυτό που **δεν** ξαναγίνεται είναι οτιδήποτε έκανε ο κώδικάς σας κατά τη μεταγλώττιση. Τα μπλοκ `BEGIN` και ο κώδικας αρθρωμάτων που εκτελέστηκε κατά τον χρόνο `use` έτρεξαν μία φορά όταν χτίστηκε το πρότυπο· οι παρενέργειές τους είναι μέρος της εικόνας που κληρονομεί κάθε εκτέλεση. Συνέπειες που αναλαμβάνετε όταν εντάσσετε ένα σενάριο: - Το `$^T` (ο χρόνος έναρξης του σεναρίου) και η κατάσταση του τυχαίου σπόρου χρονολογούνται από τη δημιουργία του προτύπου. Αν αυτό έχει σημασία για το σενάριό σας, ξανασφραγίστε τα στην αρχή της φάσης εκτέλεσης: ```perl INIT { $^T = time; srand(); } ``` - Οι τιμές που διαβάστηκαν από το `%ENV` *κατά τη μεταγλώττιση* (μέσα σε `BEGIN` ή κατά τον χρόνο `use`) ήταν οι τιμές της εκτέλεσης που έχτισε το πρότυπο. Διαβάστε τη διαμόρφωση κατά τον χρόνο εκτέλεσης, ή σε ένα μπλοκ `INIT`, αν πρέπει να παρακολουθεί το περιβάλλον που κάλεσε. - Οι χειριστές αρχείων, οι υποδοχές ή οι συνδέσεις βάσης δεδομένων που ανοίγονται κατά τη μεταγλώττιση μοιράζονται με κάθε εκτέλεση. Ανοίγετε τις συνδέσεις κατά τον χρόνο εκτέλεσης - ο ίδιος κανόνας που ισχύει από παλιά για τους διακομιστές εφαρμογών με προφόρτωση. Αν ένα σενάριο δεν μπορεί να ικανοποιήσει αυτό το συμβόλαιο, απλώς μην το εντάξετε· το `PPERL_DAEMON=2` ισχύει ανά κλήση, όχι καθολικά. ## Η επεξεργασία του σεναρίου και η κρυφή μνήμη Ο δαίμονας αντιλαμβάνεται όταν αλλάζει το ίδιο το αρχείο του σεναρίου και ξαναχτίζει το πρότυπο αυτόματα στην επόμενη εκτέλεση - η επεξεργασία του σεναρίου σας δεν σας σερβίρει ποτέ μια ξεπερασμένη εικόνα. Οι αλλαγές σε *αρθρώματα* που φορτώνει το σενάριο δεν ανιχνεύονται αυτόματα. Αφού αλλάξετε ένα άρθρωμα, απορρίψτε το επηρεαζόμενο πρότυπο με το χέρι: ```bash pperl --daemon-reset=report.pl # forget this script's template pperl --daemon-reset # forget all templates ``` Τα πρότυπα είναι μια φραγμένη κρυφή μνήμη: το πολύ `--daemon-max-scripts` από αυτά (προεπιλογή 100), που εκδιώκονται με βάση τη μεγαλύτερη αχρησία, και το καθένα λήγει μετά το χρονικό όριο αδράνειας του δαίμονα (`--daemon-idle`, προεπιλογή 900 δευτερόλεπτα). ## Πότε το pperl καταφεύγει σε ψυχρή εκτέλεση Ο δαίμονας αρνείται - και ο πελάτης καταφεύγει σε μια κανονική εκτέλεση, σιωπηλά και ορθά - όποτε δεν θα μπορούσε να αναπαραγάγει την κλήση ακριβώς: - δεν τρέχει κανένας δαίμονας για αυτό το εκτελέσιμο pperl - οι μεταβλητές περιβάλλοντος που διαμορφώνουν την εκκίνηση του διερμηνέα διαφέρουν από αυτές του δαίμονα (`PERL_HASH_SEED`, `PERL_PERTURB_KEYS`, `PERL_RAND_SEED`, `PERL_INTERNAL_RAND_SEED`, `PERL_UNICODE`, `LANG`, οποιαδήποτε `LC_*`, οποιαδήποτε `MALLOC_*`) - οι σημαίες της γραμμής εντολών διαφέρουν από αυτές με τις οποίες χτίστηκε το πρότυπο (ένα πρότυπο αποθηκεύει μία διαμόρφωση) - το πρότυπο χτίζεται ακόμη από μια ταυτόχρονη πρώτη εκτέλεση - η κλήση είναι ένα μονόγραμμο `-e` (τα πρότυπα αποθηκεύουν σε κρυφή μνήμη αρχεία σεναρίων) - είναι σε ισχύ το `--interactive` ή το `--stats` ## Ασφάλεια και ταυτότητα Ο δαίμονας εξυπηρετεί ακριβώς έναν χρήστη: η υποδοχή του βρίσκεται σε έναν κατάλογο με δικαιώματα μόνο για τον ιδιοκτήτη και το user id του συνομιλητή κάθε σύνδεσης επαληθεύεται. Εξυπηρετεί επίσης ακριβώς ένα *build* του pperl: η υποδοχή είναι κλειδωμένη στην ταυτότητα του εκτελέσιμου (το `pperl --build-id` την εκτυπώνει), οπότε μετά από μια αναβάθμιση του pperl ο παλιός δαίμονας απλώς δεν επικοινωνείται ποτέ ξανά και τερματίζει στο χρονικό όριο αδράνειάς του. ## Περιορισμοί - Ο έλεγχος εργασιών είναι κατά προσέγγιση: το σενάριο που τρέχει είναι παιδί του δαίμονα, όχι του κελύφους σας. Τα σήματα που στέλνετε στο `pperl` (συμπεριλαμβανομένου του `Ctrl-C`) προωθούνται στο σενάριο, αλλά το `Ctrl-Z` αναστέλλει μόνο το `pperl` στο προσκήνιο, όχι τη διεργασία του σεναρίου. - Ένα πρότυπο ανά διαδρομή σεναρίου, που κρατά μία διαμόρφωση σημαιών. Η κλήση του ίδιου σεναρίου με διαφορετικές σημαίες καταφεύγει σε μια ψυχρή εκτέλεση αντί να ξαναχτίσει το πρότυπο. - Το `PPERL_DAEMON=1` (ή το `--via-daemon`) υπάρχει ως μειωμένη λειτουργία που κάνει fork έναν προαρχικοποιημένο διερμηνέα αλλά εξακολουθεί να μεταγλωττίζει το σενάριο σε κάθε εκτέλεση. Δεν εξοικονομεί σχεδόν τίποτα και είναι κυρίως χρήσιμο για τη δοκιμή του ίδιου του δαίμονα· χρησιμοποιήστε το `PPERL_DAEMON=2` για το πραγματικό όφελος.