SysV IPC

semctl#

Εκτελεί μια λειτουργία ελέγχου σε σύνολο σηματοφόρων System V.

Η semctl είναι η σύνδεση σε επίπεδο Perl για την κλήση συστήματος semctl(2). Διαβάζει ή τροποποιεί την κατάσταση του συνόλου σηματοφόρων που αναγνωρίζεται από το ID - λήψη ή ορισμός της τιμής ενός μεμονωμένου σηματοφόρου, ανάκτηση ή εγκατάσταση του πλήρους διανύσματος τιμών, ανάγνωση των συνημμένων μεταδεδομένων semid_ds, ή αφαίρεση ολόκληρου του συνόλου. Η CMD επιλέγει τη λειτουργία· το SEMNUM επιλέγει ποιος σηματοφόρος εντός του συνόλου (αγνοείται για εντολές σε όλο το σύνολο όπως IPC_STAT, IPC_RMID, GETALL, SETALL)· το ARG είναι ο ενταμιευτής εισόδου ή εξόδου της εντολής.

Η semctl είναι λεπτό wrapper - η σημασιολογία, οι σταθερές εντολών και το σχήμα του ARG προέρχονται όλα απευθείας από την κλήση επιπέδου C. Σχεδόν πάντοτε θα θέλετε:

use IPC::SysV;

πρώτα, για να εισαγάγετε τις σταθερές IPC_STAT, IPC_RMID, GETVAL, SETVAL, GETALL, SETALL, GETPID, GETNCNT, GETZCNT.

Σύνοψη#

semctl $id, $semnum, $cmd, $arg
semctl $id, 0,       IPC_RMID, 0            # destroy set
semctl $id, $n,      SETVAL,   $value       # set one
semctl $id, 0,       SETALL,   $packed      # set all

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

Η επιστροφή ακολουθεί την ίδια σύμβαση με την ioctl:

  • undef σε σφάλμα (με το $! τεθειμένο).

  • Τη συμβολοσειρά "0 but true" όταν η υποκείμενη κλήση επέστρεψε 0 - αυτή η συμβολοσειρά είναι ψευδής αριθμητικά (οπότε τυπώνει 0 σε αριθμητικό περιβάλλον) αλλά αληθής σε λογικό περιβάλλον, επιτρέποντάς σας να διακρίνετε την επιτυχία-με-μηδέν από την αποτυχία σε έναν έλεγχο.

  • Την πραγματική ακέραια τιμή επιστροφής διαφορετικά.

Ο ιδιωματικός έλεγχος είναι επομένως:

my $rc = semctl($id, $n, GETVAL, 0);
defined $rc or die "semctl: $!";

Ελέγξτε defined, όχι αλήθεια - μια νόμιμα μηδενική τιμή σηματοφόρου θα αποτύγχανε σε απλό if ($rc).

Για τιμές CMD που διαβάζουν δεδομένα στο ARG (IPC_STAT, GETALL), το ARG πρέπει να είναι τροποποιήσιμη lvalue (απλή μεταβλητή, όχι κυριολεκτικό ή έκφραση)· σε επιτυχία ο ενταμιευτής αντικαθίσταται επιτόπου με τα επιστρεφόμενα bytes και κάνετε εσείς unpack.

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

Θέτει το $! σε αποτυχία. Καμία άλλη καθολική του διερμηνέα δεν εμπλέκεται.

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

Διαβάστε την τρέχουσα τιμή ενός μεμονωμένου σηματοφόρου:

use IPC::SysV qw(GETVAL);
my $value = semctl($id, $semnum, GETVAL, 0);
defined $value or die "GETVAL: $!";

Θέστε έναν μεμονωμένο σηματοφόρο:

use IPC::SysV qw(SETVAL);
semctl($id, $semnum, SETVAL, 1)
    or die "SETVAL: $!";

Διαβάστε όλες τις τιμές σηματοφόρων ταυτόχρονα. Ο ενταμιευτής πρέπει να προεκχωρηθεί στο σωστό μέγεθος - nsems εγγενή shorts - πριν την κλήση. Η pack με ανενεργό μετρητή είναι ο συνηθισμένος τρόπος:

use IPC::SysV qw(GETALL);
my $nsems = 4;
my $buf   = pack("s!*", (0) x $nsems);      # allocate room
semctl($id, 0, GETALL, $buf) or die $!;
my @vals = unpack("s!*", $buf);

Εγκαταστήστε ένα πλήρες σύνολο τιμών:

use IPC::SysV qw(SETALL);
my $buf = pack("s!*", 1, 0, 0, 1);
semctl($id, 0, SETALL, $buf)
    or die "SETALL: $!";

Ανακτήστε τη δομή semid_ds για το σύνολο. Το ARG γράφεται επιτόπου με την πακεταρισμένη δομή· η διάταξή της είναι ειδική της πλατφόρμας, οπότε κάντε unpack με τη βοήθεια του IPC::Semaphore αντί χειρωνακτικά εκτός αν χρειάζεται:

use IPC::SysV qw(IPC_STAT);
my $ds = "";
semctl($id, 0, IPC_STAT, $ds)
    or die "IPC_STAT: $!";

Καταστρέψτε το σύνολο σηματοφόρων. Τα SEMNUM και ARG δεν χρησιμοποιούνται· περάστε 0:

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

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

  • Το ARG πρέπει να είναι πραγματική μεταβλητή για εντολές ανάγνωσης. Οι GETALL και IPC_STAT γράφουν στο ARG· το πέρασμα κυριολεκτικού (semctl($id, 0, GETALL, "")) ή έκφρασης μόνο για ανάγνωση είναι σφάλμα χρόνου εκτέλεσης. Τα υπάρχοντα περιεχόμενα της μεταβλητής αντικαθίστανται, δεν προστίθενται.

  • Το ARG πρέπει να είναι προδιαστασιολογημένο. Ο πυρήνας γράφει ακριβώς nsems * sizeof(short) bytes για την GETALL, ή sizeof(struct semid_ds) για την IPC_STAT. Το πέρασμα μικρότερου ενταμιευτή είναι απροσδιόριστη συμπεριφορά στην υποκείμενη κλήση C· το pack("s!*", (0) x $nsems) είναι το τυπικό ιδίωμα για την GETALL.

  • Εγγενές short, όχι φορητό short. Οι τιμές σηματοφόρου είναι C short (προσημασμένα, τυπικά 16-bit). Χρησιμοποιήστε s! στις pack / unpack - το ! επιλέγει τον εγγενή τύπο της πλατφόρμας. Το σκέτο s εξαναγκάζει 16-bit little-endian και θα παραγάγει εσφαλμένα αποτελέσματα σε συστήματα big-endian ή LP64-short.

  • Επιστροφές "0 but true". Η GETVAL σε σηματοφόρο του οποίου η τιμή είναι 0, οι GETPID/GETNCNT/GETZCNT που επιστρέφουν μηδέν, και άλλες επιτυχίες με μηδενική τιμή επιστρέφουν όλες την κυριολεκτική συμβολοσειρά "0 but true". Τα αριθμητικά περιβάλλοντα βλέπουν 0· τα λογικά περιβάλλοντα βλέπουν αληθές. Χρησιμοποιήστε defined για να ελέγξετε αποτυχία.

  • Το SEMNUM αγνοείται για εντολές σε όλο το σύνολο. Οι IPC_STAT, IPC_RMID, SETALL, GETALL ενεργούν επί ολόκληρου του συνόλου. Περάστε 0 συμβατικά· το πέρασμα οποιασδήποτε άλλης τιμής είναι αβλαβές αλλά συσκοτίζει την πρόθεση.

  • Μετά την IPC_RMID το id είναι άκυρο. Κάθε επόμενη semctl ή semop στο $id αποτυγχάνει με EINVAL / EIDRM. Μην αποθηκεύσετε το id σε cache πέρα από την αφαίρεση.

  • Το σύνολο είναι καθολικό στον πυρήνα και διατηρείται μεταξύ εξόδων διεργασιών. Ένα σύνολο που δημιουργήθηκε από κατεστραμμένο σενάριο παραμένει μέχρι να καλέσει κάποιος IPC_RMID (ή να επανεκκινήσει το σύστημα). Χρησιμοποιήστε ipcs -s / ipcrm -s από το κέλυφος για να επιθεωρήσετε ή να καθαρίσετε διαρρεύσαντα σύνολα.

  • Τα δικαιώματα προέρχονται από τη semget. Το IPC_CREAT | mode που περνά κατά τη δημιουργία ελέγχει ποιος μπορεί να εκδώσει ποιες εντολές semctl. Το EACCES από την semctl σημαίνει ότι τα mode bits δεν επιτρέπουν τη ζητούμενη λειτουργία για τον τρέχοντα ενεργό uid.

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

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

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

  • semget - δημιουργήστε ή αναζητήστε το σύνολο σηματοφόρων του οποίου το id περνάτε στη συνέχεια στη semctl

  • semop - οι πραγματικές λειτουργίες wait / signal· η semctl είναι για έλεγχο και επιθεώρηση, η semop κάνει τη δουλειά

  • msgctl - η αντίστοιχη κλήση ελέγχου για ουρές μηνυμάτων System V· ίδια σύμβαση τιμής επιστροφής

  • shmctl - η αντίστοιχη κλήση ελέγχου για κοινόχρηστη μνήμη System V· ίδια σύμβαση τιμής επιστροφής

  • pack - πώς να κατασκευάσετε τον ενταμιευτή ARG με s! για τιμές σηματοφόρου και τη δομή semid_ds

  • IPC::Semaphore - αντικειμενικό wrapper που κρύβει τη semctl πίσω από ονομασμένες μεθόδους· επιλέξτε το όταν ένα σενάριο κάνει πάνω από μία ή δύο κλήσεις