SysV IPC

msgget#

Δημιουργεί ή αναζητά μια ουρά μηνυμάτων System V IPC και επιστρέφει το id της.

Η msgget είναι το σημείο εισόδου στην οικογένεια ουράς μηνυμάτων System V: κάθε επόμενη κλήση msgsnd, msgrcv ή msgctl χρειάζεται ένα id, και από εδώ προκύπτει αυτό το id. Το KEY ονοματίζει την ουρά σε όλο το σύστημα (ένας ακέραιος key_t, τυπικά κατασκευασμένος με IPC::SysV::ftok ή η ειδική τιμή IPC_PRIVATE). Το FLAGS είναι το bitwise-or των bits δικαιωμάτων (τα κάτω εννέα, ίδια διάταξη με τα modes αρχείων) και προαιρετικών σημαιών IPC_CREAT / IPC_EXCL. Η κλήση είναι άμεσο περιτύλιγμα γύρω από την κλήση συστήματος msgget(2).

Σύνοψη#

use IPC::SysV qw(IPC_CREAT IPC_EXCL IPC_PRIVATE S_IRUSR S_IWUSR);

my $id = msgget($key, IPC_CREAT | 0600);
my $id = msgget(IPC_PRIVATE, 0600);
my $id = msgget($key, IPC_CREAT | IPC_EXCL | 0600);

Τι επιστρέφεται#

Ένας μη αρνητικός ακέραιος id ουράς μηνυμάτων σε επιτυχία, ή undef σε αποτυχία (με την $! ορισμένη στην τιμή errno από την υποκείμενη κλήση συστήματος). Το id είναι αδιαφανές handle - μη κάνετε αριθμητική πάνω του, απλώς περάστε το πίσω στις άλλες ενσωματωμένες msg*.

my $id = msgget($key, IPC_CREAT | 0600)
    // die "msgget($key) failed: $!";

Καθολική κατάσταση που επηρεάζει#

  • $! - ορίζεται σε αποτυχία στο errno από την msgget(2) (συνήθως EACCES, EEXIST, ENOENT, ENOSPC, ENOMEM).

Δεν εμπλέκονται άλλες ειδικές μεταβλητές. Η ίδια η ουρά ζει στον πυρήνα, όχι στη διεργασία Perl, και διατηρείται μετά από exec και αφότου εξέλθει η διεργασία που τη δημιούργησε - πρέπει να αφαιρεθεί ρητά με msgctl και IPC_RMID.

Παραδείγματα#

Δημιουργήστε ιδιωτική ουρά που καμία άλλη διεργασία δεν μπορεί να ονοματίσει - η συνήθης επιλογή όταν η ουρά μοιράζεται μόνο με παιδιά αυτής της διεργασίας:

use IPC::SysV qw(IPC_PRIVATE);
my $id = msgget(IPC_PRIVATE, 0600) // die "msgget: $!";

Δημιουργήστε ή προσαρτηθείτε σε επώνυμη ουρά χρησιμοποιώντας ένα key_t παραγόμενο από διαδρομή αρχείου. Η ftok μετατρέπει διαδρομή συν ένα id έργου ενός χαρακτήρα σε σταθερό κλειδί ώστε άσχετες διεργασίες να μπορούν να συμφωνούν σε μια ουρά:

use IPC::SysV qw(ftok IPC_CREAT);
my $key = ftok("/var/run/myapp", 'M');
my $id  = msgget($key, IPC_CREAT | 0600) // die "msgget: $!";

Δημιουργία αποκλειστικά - αποτυχία αν η ουρά υπάρχει ήδη. Έτσι ανιχνεύετε ότι ένα προηγούμενο στιγμιότυπο του προγράμματός σας υπάρχει ακόμη:

use IPC::SysV qw(IPC_CREAT IPC_EXCL);
my $id = msgget($key, IPC_CREAT | IPC_EXCL | 0600);
if (!defined $id) {
    die "queue already exists" if $!{EEXIST};
    die "msgget: $!";
}

Προσάρτηση σε υπάρχουσα ουρά χωρίς δημιουργία νέας - παραλείψτε το IPC_CREAT. Επιστρέφει undef με την $! ορισμένη σε ENOENT αν δεν υπάρχει τέτοια ουρά:

my $id = msgget($key, 0) // die "no queue for key $key: $!";

Αφαιρέστε την ουρά όταν τελειώσετε. Η ίδια η msgget δεν έχει αντίστοιχο αποδόμησης· η αφαίρεση γίνεται μέσω της msgctl:

use IPC::SysV qw(IPC_RMID);
msgctl($id, IPC_RMID, 0) or warn "msgctl IPC_RMID: $!";

Οριακές περιπτώσεις#

  • Το KEY πρέπει να είναι ακέραιος, τυπικά key_t. Η παροχή συμβολοσειράς πυροδοτεί τους συνήθεις κανόνες αριθμητικής μετατροπής και σχεδόν σίγουρα θα ονοματίσει λάθος ουρά. Κατασκευάστε κλειδιά με IPC::SysV::ftok ή χρησιμοποιήστε IPC_PRIVATE.

  • Το IPC_PRIVATE δημιουργεί πάντα νέα ουρά, ανεξάρτητα από το αν έχει τεθεί το IPC_CREAT. Το κλειδί δεν είναι επαναχρησιμοποιήσιμο - δεν μπορείτε αργότερα να καλέσετε msgget για την ίδια ουρά από άσχετη διεργασία χρησιμοποιώντας IPC_PRIVATE.

  • Τα bits δικαιωμάτων εφαρμόζονται σε κάθε κλήση, όχι μόνο στη δημιουργία. Η προσάρτηση σε υπάρχουσα ουρά χωρίς IPC_CREAT ελέγχει και πάλι τα bits δικαιωμάτων έναντι του ιδιοκτήτη/ομάδας της ουράς και του ενεργού uid/gid της τρέχουσας διεργασίας. Bits που δεν ταιριάζουν δίνουν EACCES.

  • Το IPC_EXCL χωρίς IPC_CREAT δεν έχει νόημα - ο πυρήνας το αγνοεί. Αν θέλετε αποκλειστική δημιουργία, ζευγαρώνετέ τα πάντα.

  • Όρια σε επίπεδο συστήματος. Η δημιουργία μπορεί να αποτύχει με ENOSPC όταν χτυπηθεί το όριο MSGMNI του πυρήνα, ή με ENOMEM υπό πίεση μνήμης. Αυτά δεν είναι σφάλματα του προγράμματός σας· είναι λειτουργικές συνθήκες.

  • Ο χρόνος ζωής της ουράς ξεπερνά τις διεργασίες. Μια ουρά που δημιουργείται εδώ διατηρείται μέχρι να αφαιρεθεί ρητά με msgctl και IPC_RMID, ή μέχρι να επανεκκινήσει το σύστημα. Ξεχασμένες ουρές διαρρέουν πόρους πυρήνα που τα ipcs και ipcrm χρησιμοποιούνται για να εντοπίσουν και να καθαρίσουν.

  • Δεν διαθέτουν όλα τα συστήματα ουρές μηνυμάτων SysV. Σε πλατφόρμες που τις παραλείπουν, η ενσωματωμένη συνάρτηση κράζει με msgget not implemented on this architecture. Η προειδοποίηση φορητότητας στο upstream POD ισχύει.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • msgsnd - στέλνει μήνυμα στην ουρά που επέστρεψε η msgget

  • msgrcv - λαμβάνει μήνυμα από αυτή την ουρά

  • msgctl - διερωτάται, θέτει επιλογές ή αφαιρεί την ουρά· η αποδόμηση μετά την msgget περνά από εδώ

  • semget - ίδιο σχήμα API για σηματοφόρους System V όταν χρειάζεστε συγχρονισμό αντί για μεταφορά δεδομένων

  • shmget - ίδιο σχήμα API για κοινή μνήμη System V όταν χρειάζεστε άμεσο διαμοιρασμό μνήμης αντί για ανταλλαγή μηνυμάτων

  • IPC::SysV - παρέχει το ftok και τις σταθερές IPC_* / S_* που η msgget περιμένει στο FLAGS