I/O · Filehandles, αρχεία, κατάλογοι
select#
Είτε ορισμός του προεπιλεγμένου filehandle εξόδου, είτε κλήση της κλήσης συστήματος select(2) για πολυπλεξία I/O. Ίδιο όνομα, δύο ασυσχέτιστες δουλειές - διακρίνονται από τον αριθμό ορισμάτων.
Η μορφή ενός ορίσματος (ή μηδέν ορισμάτων) αφορά πού στέλνουν την έξοδό τους οι print, printf, say και write όταν δεν ονοματίζετε filehandle. Η μορφή τεσσάρων ορισμάτων είναι άμεσο περιτύλιγμα γύρω από την κλήση συστήματος BSD select(2) για αναμονή σε σύνολα περιγραφέων αρχείου.
Σύνοψη#
select FILEHANDLE # set default output handle, return old
select # return current default output handle
select RBITS, WBITS, EBITS, TIMEOUT # select(2) syscall
Τι επιστρέφεται#
Η select FILEHANDLE επιστρέφει το προηγουμένως επιλεγμένο filehandle (ως typeglob), οπότε το ιδιωματικό μοτίβο save/restore λειτουργεί:
my $old = select $fh;
$| = 1;
select $old;
Η select (χωρίς ορίσματα) επιστρέφει το τρέχον επιλεγμένο filehandle. Κατά την εκκίνηση του προγράμματος αυτό είναι το STDOUT.
Η select RBITS, WBITS, EBITS, TIMEOUT επιστρέφει διαφορετικά πράγματα σε διαφορετικά περιβάλλοντα:
Σε βαθμωτό περιβάλλον: ο αριθμός των έτοιμων filehandles, ή
-1σε σφάλμα με την$!ορισμένη.Σε περιβάλλον λίστας:
($nfound, $timeleft)- το ίδιο$nfoundσυν τον υπολειπόμενο χρόνο από τοTIMEOUT. Πολλοί πυρήνες δεν ενημερώνουν το$timeleft· σε αυτά τα συστήματα είναι πάντα ίσο με το είσοδοTIMEOUT.
Στη λήξη του timeout το $nfound είναι 0. Οι τρεις bit masks (RBITS, WBITS, EBITS) ενημερώνονται επιτόπου ώστε να υποδείξουν ποιοι περιγραφείς είναι έτοιμοι - περάστε αντίγραφα αν θέλετε να διατηρήσετε τα αρχικά masks.
Καθολική κατάσταση που επηρεάζει#
Η μορφή ενός ορίσματος αλλάζει ένα κομμάτι καθολικής κατάστασης διερμηνέα: το τρέχον επιλεγμένο filehandle εξόδου. Όσο αυτό το handle είναι επιλεγμένο, αυτές οι μεταβλητές αναφέρονται σε αυτό, όχι στο STDOUT:
Γι” αυτό το my $old = select($fh); $| = 1; select($old); λειτουργεί: το $| είναι ιδιότητα του επιλεγμένου handle, όχι καθολικό βαθμωτό.
Η μορφή τεσσάρων ορισμάτων δεν αγγίζει κάποια κατάσταση ανά διερμηνέα. Μπορεί να αφήσει την $! ορισμένη σε σφάλμα.
Παραδείγματα#
Ενεργοποίηση αυτόματης εκκένωσης σε ένα handle χωρίς ενόχληση του προεπιλεγμένου:
my $old = select $fh; $| = 1; select $old;
Προσωρινή ανακατεύθυνση της print και αποκατάσταση στην έξοδο από το μπλοκ:
{
my $old = select $log_fh;
print "entry: $msg\n"; # goes to $log_fh
select $old;
}
Αναμονή για 250 χιλιοστά του δευτερολέπτου χρησιμοποιώντας τη μορφή τεσσάρων ορισμάτων:
select undef, undef, undef, 0.25;
Αναμονή έως 5 δευτερολέπτων μέχρι το STDIN να γίνει αναγνώσιμο:
my $rin = '';
vec($rin, fileno(STDIN), 1) = 1;
my $nfound = select my $rout = $rin, undef, undef, 5;
if ($nfound) {
my $line = <STDIN>;
}
Κατασκευή read mask πάνω σε πολλαπλά handles:
sub fhbits {
my $bits = '';
vec($bits, fileno($_), 1) = 1 for @_;
return $bits;
}
my $rin = fhbits(\*STDIN, $sock);
my ($nfound, $timeleft) =
select my $rout = $rin, undef, undef, 10;
Οριακές περιπτώσεις#
Εναλλακτική σε στυλ μεθόδου. Το
$fh->autoflush(1)θέτει τη σημαία αυτόματης εκκένωσης στο$fhχωρίς να αλλάζει το προεπιλεγμένο handle. Προτιμήστε το όταν χρειάζεται μόνο να αλλάξετε μία ιδιότητα ενός handle - καμία καθολική κατάσταση δεν εμπλέκεται.Η εντοπιοποίηση typeglob είναι καθαρότερη για ανακατευθύνσεις με εμβέλεια. Το
local *STDOUT = $fhεπανασυνδέει το ίδιο τοSTDOUTγια τη δυναμική εμβέλεια· σεdieτο αρχικό αποκαθίσταται αυτόματα. Ηselectδεν αποκαθιστά σεdie. Τα δύο δεν είναι ισοδύναμα: με τηselectμια ρητήprint STDOUT ...εξακολουθεί να φτάνει στο πραγματικόSTDOUT· με τη μορφήlocal *STDOUT, ακόμη και ηprint STDOUT ...πάει στο επανασυνδεδεμένο handle.Η μορφή bit-mask απαιτεί bytes, όχι λίστα ακεραίων fileno. Ένα bit mask είναι πακεταρισμένη bit string που κατασκευάζεται με
vec· το πέρασμα λίστας ακεραίων ή αναφοράς παράγει σιωπηρά λάθος αποτελέσματα (ή κενό mask).Το
undefγια mask σημαίνει «μην περιμένεις σε αυτό το σύνολο». Περάστεundefγια masks που δεν σας ενδιαφέρουν. Κενή συμβολοσειρά''τεχνικά λειτουργεί επίσης αλλά είναι λιγότερο ιδιωματική.Τα κλασματικά timeouts λειτουργούν. Το
TIMEOUTείναι float σε δευτερόλεπτα. Το0.25είναι 250 ms· το0επιστρέφει άμεσα (polling).Το
TIMEOUTμεundefσημαίνει μπλοκάρισμα επ” αόριστον μέχρι τουλάχιστον ένας περιγραφέας να είναι έτοιμος ή να φτάσει σήμα.Τα masks τροποποιούνται επιτόπου. Κατά την επιστροφή, κάθε mask κρατά μόνο τα bits για τους έτοιμους περιγραφείς. Αν χρειάζεστε τα αρχικά αργότερα, περάστε αντίγραφα - το ιδίωμα
my $rout = $rinστη γραμμή κλήσης κάνει ακριβώς αυτό.Μην αναμειγνύετε ενταμιευμένο I/O με τη μορφή τεσσάρων ορισμάτων. Η
selectαναφέρει ετοιμότητα σε επίπεδο πυρήνα· οιreadline,read, και ο τελεστής διαμαντιού<>διαβάζουν μέσω buffers PerlIO που μπορεί ήδη να κρατούν μη διαβασμένα δεδομένα τα οποία ο πυρήνας δεν γνωρίζει. Χρησιμοποιήστεsysreadγια δεδομένα μόλις ηselectπει ότι ένας περιγραφέας είναι έτοιμος.Πλασματική ετοιμότητα σε υποδοχές. Σε ορισμένα Unix η
select(2)μπορεί να αναφέρει μια υποδοχή ως «έτοιμη για ανάγνωση» όταν μια ακόλουθηreadθα μπλόκαρε ακόμα. ΘέστεO_NONBLOCKστην υποδοχή αν αυτό έχει σημασία.Η συμπεριφορά επανεκκίνησης μετά από σήμα εξαρτάται από το σύστημα. Ένα σήμα (π.χ.
SIGALRM) μπορεί να προκαλέσει τηνselectνα επιστρέψει νωρίς με$! == EINTR, ή ο πυρήνας μπορεί να επανεκκινήσει την κλήση διαφανώς. Φορητός κώδικας ελέγχει ρητά γιαEINTR.Ο αριθμός ορισμάτων διακρίνει τις δύο μορφές. Ένα όρισμα (ή κανένα) είναι η μορφή προεπιλεγμένου handle· ακριβώς τέσσερα είναι η μορφή κλήσης συστήματος. Άλλοι αριθμοί είναι συντακτικό σφάλμα.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
print- διαβάζει το επιλεγμένο handle όταν δεν δίνεται filehandle· ηselectείναι ο τρόπος να αλλάξετε ποιο handle είναι αυτόprintf- ίδιος κανόνας προεπιλεγμένου handle με τηνprintwrite- έξοδος βασισμένη σε format· οι μεταβλητές top-of-form και μήκους σελίδας ακολουθούν το επιλεγμένο handle, όχι τοSTDOUTfileno- αντιστοιχίζει ένα filehandle στον ακέραιο αριθμό περιγραφέα που χρειάζεστε κατά την κατασκευή ενός maskvec- πακετάρει αριθμούς περιγραφέων στο bit string που αναμένει η μορφή τεσσάρων ορισμάτωνsysread- η μη ενταμιευμένη ανάγνωση που χρησιμοποιείτε αφού ηselectτεσσάρων ορισμάτων πει ότι ένας περιγραφέας είναι έτοιμοςIO::Select- αντικειμενικό περιτύλιγμα πάνω από τη μορφή τεσσάρων ορισμάτων που αποκρύπτει την αριθμητική των bit-masks