SysV IPC

semget#

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

Η semget είναι το σημείο εισόδου στο API σηματοφόρων SysV. Περιτυλίγει την κλήση συστήματος semget(2): δοθέντος αριθμητικού KEY που κατονομάζει το σύνολο, του αριθμού σηματοφόρων NSEMS στο σύνολο, και μιας λέξης FLAGS που συνδυάζει bits δικαιωμάτων με σημαίες δημιουργίας, ο πυρήνας είτε επιστρέφει το id ενός αντίστοιχου υπάρχοντος συνόλου, είτε, αν το IPC_CREAT είναι στις FLAGS, δημιουργεί ένα νέο σύνολο και επιστρέφει το id του. Το επιστρεφόμενο id είναι το handle που αναμένει κάθε άλλη κλήση σηματοφόρου (semop, semctl).

Σύνοψη#

semget KEY, NSEMS, FLAGS

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

Το αναγνωριστικό του συνόλου σηματοφόρων (μη αρνητικός ακέραιος) σε επιτυχία, ή undef σε αποτυχία με το $! τεθειμένο στο errno της υποκείμενης κλήσης semget(2). Το id δεν είναι περιγραφέας αρχείου - είναι ένα handle SysV IPC σε επίπεδο πυρήνα που επιβιώνει της διεργασίας σας και διατηρείται μέχρι να αφαιρεθεί ρητά με semctl($id, 0, IPC_RMID, 0).

use IPC::SysV qw(IPC_CREAT IPC_PRIVATE);

my $semid = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)
    // die "semget: $!";

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

  • $! - τίθεται στην τιμή errno από την semget(2) σε αποτυχία (EACCES, EEXIST, ENOENT, ENOSPC, EINVAL, ENOMEM).

Το όρισμα KEY#

Το KEY είναι ακέραιος που κατονομάζει το σύνολο σηματοφόρων σε επίπεδο συστήματος. Τρεις συμβάσεις έχουν σημασία:

  • IPC_PRIVATE (εισάγεται από το IPC::SysV) - ο πυρήνας εκχωρεί ένα φρέσκο κλειδί που δεν χρησιμοποιείται από κανένα άλλο σύνολο. Το προκύπτον id είναι γνωστό μόνο σε αυτή τη διεργασία και σε όποιον της περάσει το id, τυπικά παιδιά μετά από fork. Χρησιμοποιήστε αυτό όταν το σύνολο είναι λεπτομέρεια υλοποίησης ενός δέντρου διεργασιών.

  • Σταθερό ακέραιο κυριολεκτικό - κάθε συνεργαζόμενη διεργασία κωδικοποιεί σταθερά τον ίδιο αριθμό. Εύθραυστο μεταξύ άσχετων προγραμμάτων που μπορεί να επιλέξουν τον ίδιο ακέραιο.

  • Κλειδί παραγόμενο από την ftok(3) - η IPC::SysV::ftok($path, $proj_id) μετατρέπει μια διαδρομή στο filesystem συν ένα project byte σε αριθμητικό κλειδί. Η τυπική συνταγή για άσχετες διεργασίες που χρειάζεται να συμφωνήσουν σε κλειδί χωρίς να κωδικοποιήσουν σταθερά έναν μαγικό αριθμό.

Το όρισμα FLAGS#

Το FLAGS συνδυάζει bits δικαιωμάτων (κατώτερα 9 bits, όπως ένα mode chmod: 0600, 0660, 0666) με σημαίες δημιουργίας από το IPC::SysV:

  • IPC_CREAT - δημιουργεί το σύνολο αν δεν υπάρχει ήδη. Χωρίς αυτή τη σημαία, η semget αναζητά μόνο υπάρχον σύνολο με το δοσμένο κλειδί.

  • IPC_CREAT | IPC_EXCL - δημιουργεί το σύνολο, αλλά αποτυγχάνει με EEXIST αν υπάρχει ήδη ένα για το KEY. Το αντίστοιχο SysV του O_CREAT | O_EXCL στην open.

Τα bits δικαιωμάτων ελέγχονται από τον πυρήνα σε κάθε επόμενη κλήση semop και semctl έναντι του uid/gid της επικαλούμενης διεργασίας.

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

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

use IPC::SysV qw(IPC_PRIVATE IPC_CREAT);
my $semid = semget(IPC_PRIVATE, 3, IPC_CREAT | 0600)
    // die "semget: $!";

Αναζητήστε ένα υπάρχον, ονομασμένο σύνολο χωρίς να το δημιουργήσετε. Το NSEMS πρέπει να ταιριάζει με το μέγεθος με το οποίο δημιουργήθηκε το σύνολο, ή μπορεί να είναι 0 αν δεν σας ενδιαφέρει:

use IPC::SysV qw(ftok);
my $key   = ftok("/var/run/myapp.pid", ord('M'));
my $semid = semget($key, 0, 0) // die "no set for key $key: $!";

Ιδίωμα create-or-open - δοκιμάστε αποκλειστική δημιουργία, με εφεδρεία την αναζήτηση. Η πρώτη διεργασία που περνά αρχικοποιεί το σύνολο· οι επόμενες απλώς συνδέονται:

use IPC::SysV qw(ftok IPC_CREAT IPC_EXCL);

my $key = ftok("/var/run/myapp.pid", ord('M'));
my $semid = semget($key, 4, IPC_CREAT | IPC_EXCL | 0660);
if (defined $semid) {
    # We created it - initialise every semaphore to 1.
    semctl($semid, 0, SETALL, pack("s!*", (1) x 4))
        or die "SETALL: $!";
} else {
    $semid = semget($key, 4, 0) // die "semget lookup: $!";
}

Αφαιρέστε ένα σύνολο όταν τελειώσετε με αυτό. Τα σύνολα SysV διαρρέουν μεταξύ εξόδων διεργασιών - τίποτα δεν τα καθαρίζει για εσάς:

use IPC::SysV qw(IPC_RMID);
semctl($semid, 0, IPC_RMID, 0) or warn "semctl RMID: $!";

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

  • NSEMS σε αναζήτηση: όταν αναζητάτε ένα υπάρχον σύνολο (χωρίς IPC_CREAT), NSEMS ίσο με 0 σημαίνει «οποιοδήποτε μέγεθος»· μια θετική τιμή πρέπει να είναι μικρότερη ή ίση από το πραγματικό μέγεθος του συνόλου, αλλιώς η semget αποτυγχάνει με EINVAL.

  • Το IPC_PRIVATE εξακολουθεί να υπακούει στις FLAGS: εφαρμόζονται τα bits δικαιωμάτων. Ένα σύνολο που δημιουργήθηκε με 0400 είναι μόνο για ανάγνωση ακόμη και για τη διεργασία που το δημιούργησε, για κλήσεις semop που το τροποποιούν.

  • Όρια πυρήνα: η semget μπορεί να αποτύχει με ENOSPC όταν το όριο συνόλων σηματοφόρου σε επίπεδο συστήματος φτάσει στο τέλος, ή EINVAL όταν το NSEMS υπερβαίνει το μέγιστο ανά σύνολο. Δείτε ipcs -sl για τα τρέχοντα όρια σε Linux.

  • Leaked sets: a set persists until IPC_RMID or reboot. Long-running daemons that forget to remove their sets accumulate them; ipcs -s lists the survivors, ipcrm -s $id removes one.

  • Key collisions: two unrelated programs picking the same hard-coded KEY will see each other’s set - hence the ftok(3) idiom.

  • Όχι filehandle: το $semid είναι ακέραιος, όχι handle. Μην το περάσετε σε close, fcntl, ή σε οποιαδήποτε λειτουργία filehandle.

  • Τα forks κληρονομούν ids, όχι ιδιοκτησία: ένα παιδί βλέπει την ίδια τιμή $semid με τον γονέα και μπορεί να τη χρησιμοποιήσει, αλλά το ίδιο το σύνολο ανήκει στον uid που το δημιούργησε, όχι σε κάποια συγκεκριμένη διεργασία.

  • Αριθμητικό περιβάλλον: το id είναι απλός ακέραιος, ασφαλές για εκτύπωση, σύγκριση και αποθήκευση σε αρχείο ώστε να το παραλάβει άλλη διεργασία.

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

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

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

  • semop - εκτελέστε λειτουργίες wait/signal επί του συνόλου που επιστρέφει η semget

  • semctl - λειτουργίες ελέγχου επί του συνόλου: αρχικοποίηση τιμών (SETALL, SETVAL), ανάγνωσή τους (GETALL, GETVAL), και αφαίρεση του συνόλου (IPC_RMID)

  • msgget - το αντίστοιχο για ουρά μηνυμάτων, ίδιες συμβάσεις KEY, FLAGS

  • shmget - το αντίστοιχο για κοινόχρηστη μνήμη, ίδιες συμβάσεις KEY, FLAGS

  • IPC::SysV - εισάγει τα IPC_CREAT, IPC_EXCL, IPC_PRIVATE, IPC_RMID, SETALL, GETALL, και τον βοηθό ftok

  • IPC::Semaphore - αντικειμενικό wrapper γύρω από τις ωμές ενσωματωμένες sem* όταν προτιμάτε να μη πακετάρετε δομές χειρωνακτικά