msgctl#
Εκτελεί μια λειτουργία ελέγχου σε ουρά μηνυμάτων IPC System V.
Η msgctl είναι άμεσο wrapper γύρω από την κλήση συστήματος C msgctl(2). Επιθεωρεί, τροποποιεί ή αφαιρεί την ουρά μηνυμάτων που αναγνωρίζεται από το ID. Η λειτουργία που επιλέγεται από τη CMD καθορίζει πώς χρησιμοποιείται το ARG - είτε ως περιγραφέας εισόδου, είτε ως ενταμιευτής εξόδου, είτε αγνοείται εντελώς. Οι συμβολικές σταθερές που χρειάζονται για τη CMD (IPC_STAT, IPC_SET, IPC_RMID, και σε Linux οι IPC_INFO, MSG_STAT, MSG_INFO) ζουν στο IPC::SysV, το οποίο πρέπει να εισαγάγετε πριν επιλυθούν τα ονόματα.
Σύνοψη#
use IPC::SysV;
msgctl $id, IPC_STAT, $buf # read queue info into $buf
msgctl $id, IPC_SET, $buf # write queue info from $buf
msgctl $id, IPC_RMID, 0 # destroy the queue
Τι επιστρέφεται#
Η τιμή επιστροφής ακολουθεί την ίδια σύμβαση με την ioctl:
Τη συμβολοσειρά
"0 but true"όταν η υποκείμενη κλήση επέστρεψε0. Αυτή είναι η περίπτωση επιτυχίας με μηδενική τιμή - δοκιμάζεται ως αληθής σε λογικό περιβάλλον και συγκρίνεται ίση με0σε αριθμητικό περιβάλλον, οπότε ένας έλεγχος χειρίζεται τόσο επιτυχία όσο και αποτυχία.Την ακατέργαστη μη μηδενική ακέραια επιστροφή διαφορετικά (για παράδειγμα τον δείκτη που επιστρέφει η ειδική του Linux
MSG_STAT).
Η σύμβαση "0 but true" υπάρχει ακριβώς ώστε η msgctl(...) or die να κάνει το σωστό πράγμα ακόμη και όταν η κλήση συστήματος επιστρέφει νόμιμα μηδέν:
msgctl $id, IPC_RMID, 0
or die "msgctl IPC_RMID failed: $!";
Πώς χρησιμοποιείται το ARG#
Το ARG παίζει τρεις διαφορετικούς ρόλους ανάλογα με τη CMD. Ο πυρήνας αγγίζει τη μνήμη μόνο στις κατευθύνσεις που απαιτεί η εντολή:
IPC_STAT- τοARGπρέπει να είναι εγγράψιμο βαθμωτό. Ο πυρήνας το γεμίζει με την πακεταρισμένη δομήmsqid_dsπου περιγράφει την ουρά (δικαιώματα, ιδιοκτήτη, χρόνους τελευταίας αποστολής/τελευταίας λήψης, όρια bytes ουράς, καταμετρήσεις). Κάντε unpack με βοηθούς τουIPC::SysVαντί να γράψετε τη διάταξη χειρωνακτικά· ηmsqid_dsποικίλλει μεταξύ πυρήνων και εκδόσεων libc.IPC_SET- τοARGπρέπει να περιέχει πακεταρισμένηmsqid_dsπου παρήχθη από προηγούμενηIPC_STATστην ίδια (ή συμβατή) ουρά. Τιμώνται μόνο μερικά πεδία:msg_perm.uid,msg_perm.gid,msg_perm.mode(κατώτερα 9 bits) καιmsg_qbytes. Τα υπόλοιπα αγνοούνται.IPC_RMID- τοARGδεν χρησιμοποιείται. Περάστε0. Η ουρά σημειώνεται προς καταστροφή· οποιαδήποτε μπλοκαρισμένηmsgsnd/msgrcvσε αυτήν αποτυγχάνει μεEIDRM.
Μόνο σε Linux, οι MSG_STAT και MSG_INFO δέχονται επίσης εγγράψιμο βαθμωτό για το ARG και επιστρέφουν επιπλέον δεδομένα· αυτές δεν είναι φορητές και θα πρέπει να φραγούν πίσω από έλεγχο κατά τον χρόνο εκτέλεσης.
Καθολική κατάσταση που επηρεάζει#
$!- τίθεται σε αποτυχία με το errno του συστήματος (EPERM,EACCES,EINVAL,EIDRM,EFAULTείναι οι συνηθισμένες τιμές).Καμία άλλη ειδική μεταβλητή δεν επηρεάζεται.
Παραδείγματα#
Διαβάστε την κεφαλίδα της ουράς και επιθεωρήστε το τρέχον όριο bytes:
use IPC::SysV qw(IPC_STAT);
my $buf = "";
msgctl($id, IPC_STAT, $buf)
or die "msgctl IPC_STAT failed: $!";
# Layout is platform-dependent; use IPC::SysV helpers to decode.
Συρρικνώστε τον προϋπολογισμό bytes της ουράς. Πλήρης κύκλος μέσω IPC_STAT ώστε τα αμετάβλητα πεδία να διατηρήσουν τις τρέχουσες τιμές τους από τον πυρήνα:
use IPC::SysV qw(IPC_STAT IPC_SET);
my $buf = "";
msgctl($id, IPC_STAT, $buf) or die "stat: $!";
# ... modify msg_qbytes inside $buf via IPC::SysV ...
msgctl($id, IPC_SET, $buf) or die "set: $!";
Καταστρέψτε μια ουρά όταν τελειώσετε. Το ARG αγνοείται, αλλά πρέπει παρ” όλα αυτά να περαστεί - το 0 είναι ο συμβατικός placeholder:
use IPC::SysV qw(IPC_RMID);
msgctl($qid, IPC_RMID, 0)
or warn "could not remove queue $qid: $!";
Ιδιωματικός έλεγχος επιτυχίας που λειτουργεί για την περίπτωση "0 but true":
my $rc = msgctl($id, IPC_RMID, 0);
die "msgctl failed: $!" unless defined $rc; # undef = error
# $rc is now either "0 but true" or a positive integer
Οριακές περιπτώσεις#
Το
IPC::SysVδεν είναι φορτωμένο: γυμνά ονόματα σταθερών όπωςIPC_STATγίνονται barewords και, υπόuse strict, σφάλμα κατά τη μεταγλώττιση. Κάνετε πάντα πρώταuse IPC::SysV.Το βαθμωτό που περνά στο
IPC_STATδεν είναι εγγράψιμο: πεθαίνει μεModification of a read-only value attempted. Χρησιμοποιήστε απλόmy $buf = ""- όχι σταθερά, όχι κυριολεκτικό συμβολοσειράς.Αναντιστοιχία μήκους στο
IPC_SET: αν τοARGείναι μικρότερο από τηmsqid_dsτου πυρήνα, η κλήση αποτυγχάνει μεEFAULT. Ξεκινάτε πάντα από έναν ενταμιευτήIPC_STATαντί να πακετάρετε έναν από την αρχή.Αφαιρεμένη ουρά (
EIDRM): μόλις εκδοθεί ηIPC_RMID, οποιαδήποτε περαιτέρω λειτουργία στο ίδιο ID αποτυγχάνει με το$!τεθειμένο σεEIDRM, όχιEINVAL. Σενάρια που κάνουν polling σε ουρά πρέπει να αντιμετωπίζουν τοEIDRMως «η ουρά χάθηκε, σταμάτα».Σφάλματα δικαιωμάτων: οι
IPC_SETκαιIPC_RMIDαπαιτούν αντιστοίχιση ενεργού UID ήCAP_SYS_ADMIN. Ο πυρήνας επιστρέφειEPERM, όχιEACCES, για αποτυχίες ιδιοκτησίας.Παγίδα τιμής επιστροφής: το
if (msgctl(...) == 0)είναι λάθος - σε επιτυχία η τιμή είναι η συμβολοσειρά"0 but true", που μετατρέπεται σε συμβολοσειρά ως μη κενή αλλά συγκρίνεται αριθμητικά ίση με0. Δοκιμάστε μεdefinedγια την περίπτωση σφάλματος, ή βασιστείτε στοor die.Διαθεσιμότητα πλατφόρμας: το System V IPC δεν είναι καθολικό. Σε συστήματα όπου ο πυρήνας το παραλείπει, η
msgctlεγείρει την εξαίρεση χρόνου εκτέλεσηςmsgctl not implemented.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42 σε Linux. Το System V IPC είναι η μόνη υποστηριζόμενη επιφάνεια IPC· η pperl στοχεύει Linux, οπότε οι επιφυλάξεις φορητότητας που απαριθμεί το upstream perlport για μη Linux πλατφόρμες δεν ισχύουν.
Δείτε επίσης#
msgget- αποκτήστε το ID ουράς επί του οποίου λειτουργεί ηmsgctlmsgsnd- στείλτε ένα μήνυμα στην ουράmsgrcv- λάβετε ένα μήνυμα από την ουράsemctl- το αντίστοιχο για σύνολο σηματοφόρων, ίδια σύμβαση επιστροφής και ίδιο μοτίβοIPC_STAT/IPC_SET/IPC_RMIDshmctl- το αντίστοιχο για τμήμα κοινόχρηστης μνήμηςIPC::SysV- οι σταθερές (IPC_STAT,IPC_SET,IPC_RMID) και οι βοηθοί pack/unpack γιαmsqid_dsπου απαιτεί αυτή η κλήση