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:

  • $| - σημαία αυτόματης εκκένωσης

  • $, - διαχωριστικό πεδίου εξόδου

  • $\ - διαχωριστικό εγγραφής εξόδου

  • $#, $%, $=, $-, $~, $^ - μεταβλητές σχετικές με formats

Γι” αυτό το 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 με την print

  • write - έξοδος βασισμένη σε format· οι μεταβλητές top-of-form και μήκους σελίδας ακολουθούν το επιλεγμένο handle, όχι το STDOUT

  • fileno - αντιστοιχίζει ένα filehandle στον ακέραιο αριθμό περιγραφέα που χρειάζεστε κατά την κατασκευή ενός mask

  • vec - πακετάρει αριθμούς περιγραφέων στο bit string που αναμένει η μορφή τεσσάρων ορισμάτων

  • sysread - η μη ενταμιευμένη ανάγνωση που χρησιμοποιείτε αφού η select τεσσάρων ορισμάτων πει ότι ένας περιγραφέας είναι έτοιμος

  • IO::Select - αντικειμενικό περιτύλιγμα πάνω από τη μορφή τεσσάρων ορισμάτων που αποκρύπτει την αριθμητική των bit-masks