msgrcv#
Λήψη μηνύματος από ουρά μηνυμάτων System V IPC.
Η msgrcv είναι η σύνδεση Perl για την κλήση συστήματος msgrcv(2). Αντλεί ένα μήνυμα από την ουρά που προσδιορίζεται από το ID, αποθηκεύει τον τύπο μηνύματος και το payload στο VAR, και επιστρέφει αληθή τιμή σε επιτυχία ή ψευδή σε σφάλμα. Το SIZE είναι ο μέγιστος αριθμός bytes payload που ο καλών είναι διατεθειμένος να αποδεχτεί· το TYPE επιλέγει ποιο μήνυμα θα ληφθεί· το FLAGS είναι η bitmask που περνά στον πυρήνα (IPC_NOWAIT, MSG_NOERROR, κ.λπ.).
Ο επιστρεφόμενος buffer δεν είναι μόνο το σώμα του μηνύματος - τα πρώτα sizeof(long) bytes είναι ο τύπος μηνύματος που πέρασε ο αποστολέας στην msgsnd, ακολουθούμενα από το payload. Χρησιμοποιήστε unpack με πρότυπο l! a* για να τα διαχωρίσετε.
Σύνοψη#
use IPC::SysV qw(IPC_NOWAIT MSG_NOERROR);
msgrcv $qid, my $buf, 1024, 0, 0 or die "msgrcv: $!";
msgrcv $qid, my $buf, 1024, 0, IPC_NOWAIT; # non-blocking
my ($type, $payload) = unpack "l! a*", $buf;
Τι επιστρέφεται#
Αληθές σε επιτυχία, ψευδές σε σφάλμα με την $! ορισμένη. Σε επιτυχία, το VAR αντικαθίσταται με το ληφθέν frame: ένα native long (ο τύπος μηνύματος) ακολουθούμενο άμεσα από έως SIZE bytes payload. Η μεταβλητή σημειώνεται ως tainted υπό -T.
Το VAR επεκτείνεται ή συρρικνώνεται για να χωρέσει το πραγματικό μήκος του frame - δεν χρειάζεται να το προδιαστασιολογήσετε. Το περιεχόμενο πριν την κλήση απορρίπτεται.
Για να λάβετε τον τύπο και το payload ως ξεχωριστές τιμές:
my ($type, $msg) = unpack "l! a*", $buf;
Ορίσματα#
ID- το id ουράς που επιστράφηκε προηγουμένως από τηνmsgget.VAR- ένα lvalue βαθμωτό που λαμβάνει το αδρό frame. Η προηγούμενη τιμή του απορρίπτεται σε επιτυχία.SIZE- το μέγιστο μέγεθος payload σε bytes. Αν το επόμενο μήνυμα που ταιριάζει είναι μεγαλύτερο από αυτό, ηmsgrcvαποτυγχάνει μεE2BIGκαι το μήνυμα παραμένει στην ουρά - εκτός αν είναι ορισμένο τοMSG_NOERRORσταFLAGS, οπότε το μήνυμα αποκόπτεται σιωπηρά και τα επιπλέον bytes χάνονται.TYPE- επιλέγει ποιο μήνυμα θα ληφθεί:0- το πρώτο μήνυμα στην ουρά, ανεξάρτητα από τον τύπο του.θετικό
N- το πρώτο μήνυμα του οποίου ο τύπος είναι ακριβώςN.αρνητικό
-N- το πρώτο μήνυμα του χαμηλότερου τύπου που είναι<= abs(N), χρήσιμο για ουρές προτεραιότητας.
FLAGS- bitmask απόIPC_NOWAIT(άμεση επιστροφήENOMSGαντί για μπλοκάρισμα όταν δεν υπάρχει διαθέσιμο μήνυμα που ταιριάζει),MSG_NOERROR(αποκοπή αντί για αποτυχία σε υπερμεγέθη μηνύματα), και τη Linux-ειδικήMSG_EXCEPT(με θετικόTYPE, λήψη του πρώτου μηνύματος του οποίου ο τύπος δεν είναιTYPE).
Οι σταθερές βρίσκονται στο IPC::SysV· τα σκέτα ονόματα δεν γίνονται ορατά μέχρι να τα εισάγετε.
Καθολική κατάσταση που επηρεάζει#
$!- τίθεται σε σφάλμα στο υποκείμενοerrno(ENOMSG,E2BIG,EIDRM,EINVAL,EACCES,EFAULT,EINTR).Taint mode - το ληφθέν
VARσημειώνεται ως tainted, αφού το περιεχόμενό του προήλθε από άλλη διεργασία.
Παραδείγματα#
Λήψη με μπλοκάρισμα οποιουδήποτε μηνύματος, και έπειτα διαχωρισμός τύπου και payload:
use IPC::SysV qw(IPC_CREAT S_IRUSR S_IWUSR);
my $qid = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR) // die "msgget: $!";
msgrcv $qid, my $buf, 4096, 0, 0 or die "msgrcv: $!";
my ($type, $payload) = unpack "l! a*", $buf;
print "got type=$type payload=$payload\n";
Λήψη μόνο μηνυμάτων τύπου 42:
msgrcv $qid, my $buf, 4096, 42, 0 or die "msgrcv: $!";
Δημοσκόπηση χωρίς μπλοκάρισμα - άμεση επιστροφή αν η ουρά είναι κενή:
use IPC::SysV qw(IPC_NOWAIT);
use Errno qw(ENOMSG);
if (msgrcv $qid, my $buf, 4096, 0, IPC_NOWAIT) {
my ($type, $msg) = unpack "l! a*", $buf;
handle($type, $msg);
} elsif ($! == ENOMSG) {
# queue was empty; try again later
} else {
die "msgrcv: $!";
}
Αποκοπή υπερμεγέθων μηνυμάτων αντί για αποτυχία:
use IPC::SysV qw(MSG_NOERROR);
msgrcv $qid, my $buf, 64, 0, MSG_NOERROR or die "msgrcv: $!";
# payload is at most 64 bytes, excess discarded without error
Λήψη τύπου προτεραιότητας - λήψη του μηνύματος με τον χαμηλότερο αριθμό του οποίου ο τύπος είναι <= 3:
msgrcv $qid, my $buf, 4096, -3, 0 or die "msgrcv: $!";
Οριακές περιπτώσεις#
Το
VARπρέπει να είναι lvalue. Το πέρασμα σταθεράς ή βαθμωτού μόνο για ανάγνωση (για παράδειγμα ένα στοιχείο του@_που πέρασε με αναφορά σε κυριολεκτικό) εγείρειModification of a read-only value attempted.Η διάταξη του frame είναι native
long, όχι τέσσερα bytes. Σε 64-bit Linux ο τύπος καταλαμβάνει 8 bytes· σε 32-bit συστήματα καταλαμβάνει 4. Τοl!στοunpack "l! a*"- το!- είναι υποχρεωτικό· ένα σκέτοlυποθέτει 4 bytes και θα διαφθείρει payloads σε 64-bit υπολογιστές.Το
SIZEεξαιρεί την επικεφαλίδα τύπου για σκοπούς τουMSG_NOERROR. Ο πυρήνας συγκρίνει τοSIZEμε το μήκος του payload, όχι του frame. Διαστασιολογήστε τον buffer για το μεγαλύτερο payload που αναμένετε· η επικεφαλίδα τύπου γράφεται πέρα από αυτό.Διακοπή σήματος. Μια μπλοκαριστική
msgrcvεπιστρέφει ψευδές με$! == EINTRόταν φτάνει σήμα πριν να είναι διαθέσιμο μήνυμα. Επαναλάβετε την κλήση εκτός αν το σήμα προορίζεται να ματαιώσει τον βρόχο λήψης.Αφαίρεση ουράς ενώ είναι μπλοκαρισμένη. Αν άλλη διεργασία καλέσει
msgctlμεIPC_RMIDενώ αυτή η διεργασία κοιμάται στηνmsgrcv, η κλήση επιστρέφει ψευδές με$! == EIDRM.Δικαιώματα. Η λήψη απαιτεί δικαίωμα ανάγνωσης στην ουρά. Το
EACCESσημαίνει ότι η ουρά υπάρχει αλλά τα τρέχοντα uid/gid δεν ταιριάζουν με τα mode bits της ουράς.Το
TYPE = 0βλέπει σειρά FIFO. Δεν υπάρχει προτεραιότητα «οποιοδήποτε» πέραν του ρητού αρνητικούTYPE- μηνύματα όλων των τύπων αντλούνται με σειρά αποστολής.Υποστήριξη πυρήνα. Πυρήνες Linux χτισμένοι χωρίς
CONFIG_SYSVIPC, και container runtimes που δεν εκθέτουν τον χώρο ονομάτων IPC, αποτυγχάνουν κάθεmsgrcvμεENOSYS. Ελέγξτε κατά την εκκίνηση αν ο στόχος ανάπτυξής σας είναι αβέβαιος.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
msgsnd- η αντίστοιχη που τοποθετεί μηνύματα στην ουρά· το πρότυποpack "l! a*"της είναι το αντίστροφο αυτού που κάνετεunpackεδώmsgget- απόκτηση του id ουράςIDπου περνάτεmsgctl- επιθεώρηση ή διαγραφή της ουράς, συμπεριλαμβανομένου τουIPC_RMIDπου προκαλεί επιστροφήEIDRMαπό μπλοκαρισμένηmsgrcvunpack- διαχωρισμός του επιστρεφόμενου frame σε τύπο και payload μεl! a*IPC::SysV- πηγή των σταθερών σημαίαςIPC_NOWAIT,MSG_NOERRORκαι σχετικώνIPC::Msg- αντικειμενοστρεφές περιτύλιγμα που αποκρύπτει τη διαδικασία pack/unpack πίσω από μια μέθοδοrcv