sleep#
Παύει τη διεργασία για ένα πλήθος ακεραίων δευτερολέπτων.
Η sleep αναστέλλει την εκτέλεση της τρέχουσας διεργασίας για EXPR δευτερόλεπτα, ή - χωρίς όρισμα - μέχρι να την ξυπνήσει κάποιο σήμα. Το όρισμα αποκόπτεται σε ακέραιο· οι καθυστερήσεις κάτω του δευτερολέπτου απαιτούν διαφορετικό εργαλείο (βλ. παρακάτω). Η τιμή επιστροφής είναι ο αριθμός των δευτερολέπτων που κοιμήθηκε πραγματικά, που μπορεί να είναι μικρότερος από αυτόν που ζητήθηκε αν σήμα διέκοψε την κλήση.
Σύνοψη#
sleep EXPR
sleep
Τι επιστρέφεται#
Ένας ακέραιος: ο αριθμός των δευτερολέπτων κατά τα οποία ανεστάλη πραγματικά η διεργασία. Σε αδιακόπη κλήση αυτός ισούται με το (αποκομμένο) όρισμα. Αν ένα σήμα που παραδίδεται κατά τη διάρκεια του sleep αποδεσμεύσει την κλήση νωρίτερα, η τιμή επιστροφής είναι ο μικρότερος, πραγματικός χρόνος που πέρασε. Για γυμνή sleep, η τιμή είναι ό,τι κοιμήθηκε η υλοποίηση πριν φτάσει σήμα.
my $slept = sleep 10;
warn "woken early after $slept s" if $slept < 10;
Χειρισμός ορίσματος#
Θετικός ακέραιος - η κανονική περίπτωση. Κοιμάται για τόσα δευτερόλεπτα.
Μη ακέραιος (π.χ.
2.9) - το κλασματικό μέρος απορρίπτεται. Ηsleep 2.9κοιμάται δύο δευτερόλεπτα, όχι σχεδόν τρία. Για κλασματικές καθυστερήσεις χρησιμοποιήστεTime::HiRes::sleep,Time::HiRes::usleep, ή τη μορφή τεσσάρων ορισμάτων τηςselect- βλ. παρακάτω.Αρνητικός ακέραιος - η
sleepδεν κοιμάται. Εκπέμπει προειδοποίηση, θέτει την$!(errno) και επιστρέφει μηδέν.Μηδέν - η
sleep 0επιτρέπεται, αλλά εκτελεί παρ” όλα αυτά κλήση στη υποκείμενη πρωτογενή λειτουργία sleep της πλατφόρμας με όποιες παρενέργειες συνεπάγεται αυτή. Δεν είναι λοιπόν απολύτως ταυτόσημη με το να παραλείψετε την κλήση. Ειδικότερα, ηsleep 0δεν είναι το ίδιο με γυμνήsleepχωρίς όρισμα.Κανένα όρισμα - η
sleepχωρίς όρισμα κοιμάται επ” αόριστον, μέχρι να παραδοθεί σήμα. Αυτό διαφέρει από τηνsleep 0.
Διακοπή από σήματα#
Η sleep επιστρέφει νωρίτερα αν η διεργασία λάβει σήμα του οποίου ο χειριστής τρέχει (ή του οποίου η προεπιλεγμένη ενέργεια δεν τερματίζει τη διεργασία). Το κανονικό μοτίβο για μια οριοθετημένη αναμονή που μπορεί να ακυρωθεί από αλλού είναι μια alarm σε συνδυασμό με χειριστή σήματος:
eval {
local $SIG{ALRM} = sub { die "Alarm!\n" };
sleep;
};
die $@ unless $@ eq "Alarm!\n";
Επειδή η ίδια η sleep υλοποιείται συνήθως πάνω από την alarm σε συστήματα Unix, γενικά δεν μπορείτε να αναμίξετε κλήσεις alarm και sleep στο ίδιο πρόγραμμα χωρίς εκπλήξεις. Επιλέξτε μία.
Καθυστερήσεις κάτω του δευτερολέπτου#
Η sleep δέχεται εξ ορισμού μόνο ακεραίους. Για πιο λεπτόκοκκες αναμονές χρησιμοποιήστε ένα από τα:
Time::HiRes::sleep($seconds)- δέχεται κινητής υποδιαστολής αριθμό δευτερολέπτων. Από την Perl 5.8 τοTime::HiResδιανέμεται με την βασική διανομή.Time::HiRes::usleep($microseconds)- ακέραια microseconds.Η μορφή τεσσάρων ορισμάτων της
selectμε τα τρία πρώτα ορίσματαundef:select undef, undef, undef, 0.25; # sleep 250 ms
syscallστηsetitimer(2)αν η πλατφόρμα σας την υποστηρίζει και χρειάζεστε στενό έλεγχο πάνω σε χρονομετρητές.
Δείτε επίσης την POSIX::pause, που μπλοκάρει τη διεργασία μέχρι να φτάσει οποιοδήποτε σήμα - ουσιαστικά γυμνή sleep χωρίς όριο καθορισμένο από την υλοποίηση.
Παραδείγματα#
Σταθερή καθυστέρηση:
print "working...\n";
sleep 3;
print "done\n";
Βρόχος δημοσκόπησης με back-off:
until (ready()) {
sleep 1;
}
Ανίχνευση πρόωρου ξυπνήματος:
my $want = 30;
my $got = sleep $want;
if ($got < $want) {
warn "interrupted after $got of $want seconds\n";
}
Αναμονή για σήμα χωρίς να καίγεται CPU - η γυμνή sleep αναστέλλει μέχρι να φτάσει SIGALRM (ή οποιοδήποτε άλλο σήμα που πιάνεται):
$SIG{USR1} = sub { warn "got USR1\n" };
sleep; # wakes on USR1 delivery
Ακύρωση μακράς αναμονής με alarm:
eval {
local $SIG{ALRM} = sub { die "timeout\n" };
alarm 5;
sleep 3600; # at most 5 seconds really
alarm 0;
};
alarm 0;
die $@ if $@ && $@ ne "timeout\n";
Οριακές περιπτώσεις#
Η γυμνή
sleepδεν κοιμάται πραγματικά «για πάντα». Η υλοποίηση έχει μέγιστο - στην πράξη, ό,τι δέχεται η υποκείμενηsleep(3)της C ή το ισοδύναμο - αλλά για κάθε ρεαλιστικό σκοπό μπλοκάρει μέχρι να φτάσει σήμα. Αντιμετωπίστε την ως αόριστη αναμονή.sleep 0≠ καμία κλήση. Η κλήση συστήματοςsleep(0)της πλατφόρμας εκτελείται παρ” όλα αυτά. Στα περισσότερα συστήματα αυτό παραχωρεί την CPU για λίγο· μη βασίζεστε στη συγκεκριμένη συμπεριφορά σε διαφορετικές πλατφόρμες.Η
sleepέναντι του πραγματικού χρόνου. Σε παλαιότερα συστήματα ηsleepμπορούσε να επιστρέψει μέχρι και ένα ολόκληρο δευτερόλεπτο νωρίτερα λόγω αδρής μέτρησης δευτερολέπτων. Τα σύγχρονα συστήματα κοιμούνται ολόκληρη την ποσότητα, αλλά μπορούν να υπερβούν: ο χρονοπρογραμματιστής μπορεί να μην ξυπνήσει αμέσως τη διεργασία σας σε ένα απασχολημένο σύστημα. Ηsleep Nεγγυάται τουλάχιστονNδευτερόλεπτα αναστολής σε σύγχρονους πυρήνες, όχι ακριβώςN.Τα αρνητικά ορίσματα δεν περικόπτονται. Είναι σκληρό no-op που θέτει την
$!. Αν υπολογίζετε το όρισμα, επικυρώστε το πρώτα.Η ανάμιξη με
alarmείναι εύθραυστη. Ο χρονομετρητής alarm και ο χρονομετρητής sleep μπορεί να είναι ο ίδιος πόρος. Καθιερώστε μία πειθαρχία (είτεalarm+ γυμνήsleep, είτε σκέτηsleep Nχωρίς alarms) και μείνετε σε αυτήν μέσα σε ένα πρόγραμμα.Σήματα που απλώς θέτουν σημαία επίσης ξυπνούν την
sleep. Οποιοδήποτε σήμα του οποίου η παράδοση κάνει χειριστή να τρέξει επιστρέφει τον έλεγχο στην Perl· ηsleepτότε επιστρέφει νωρίτερα ακόμη και αν ο ίδιος ο χειριστής δεν κάνει τίποτα ορατό.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
alarm- προγραμματίζειSIGALRMμετά από δεδομένο αριθμό δευτερολέπτων· ο κλασικός τρόπος να οριοθετηθεί μιαsleepή οποιαδήποτε άλλη μπλοκαριστική κλήσηselect- στη μορφή τεσσάρων ορισμάτων με μη ορισμένη τριάδα readfds/writefds/exceptfds, παρέχει sleeps κάτω του δευτερολέπτουwait,waitpid- μπλοκάρει σε διεργασίες-παιδιά αντί σε χρόνοTime::HiRes::sleep- δευτερόλεπτα κινητής υποδιαστολήςTime::HiRes::usleep- ακέραια microsecondsPOSIX::pause- μπλοκάρει μέχρι να φτάσει οποιοδήποτε σήμα