SysV IPC

shmwrite#

Αντιγράφει bytes σε ένα τμήμα κοινής μνήμης System V.

Η shmwrite προσαρτάται στο τμήμα κοινής μνήμης που προσδιορίζεται από το ID, αντιγράφει έως SIZE bytes από το STRING ξεκινώντας από τη μετατόπιση byte POS μέσα στο τμήμα, και αποπροσαρτάται. Αν το STRING είναι μακρύτερο από SIZE, εγγράφονται μόνο τα πρώτα SIZE bytes· αν είναι κοντύτερο, το υπόλοιπο του παραθύρου SIZE bytes γεμίζει με μηδενικά bytes NUL. Το ID τμήματος είναι η τιμή που επέστρεψε προηγούμενη κλήση shmget (ή αποκτήθηκε από άλλη διεργασία μέσω κάποιου εκτός-ζώνης καναλιού).

Σύνοψη#

shmwrite ID, STRING, POS, SIZE

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

Αληθές σε επιτυχία, ψευδές σε σφάλμα, με την $! ορισμένη στον λόγο (τυπικά EINVAL, EACCES ή EIDRM). Σε αντίθεση με τις περισσότερες ενσωματωμένες I/O, η τιμή επιστροφής είναι απλή λογική τιμή - δεν υπάρχει παραλλαγή με μέτρηση bytes, επειδή το πλήθος είναι πάντα ακριβώς SIZE όταν η κλήση πετυχαίνει.

shmwrite($id, $payload, 0, 4096)
    or die "shmwrite($id) failed: $!";

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

  • Η $! ορίζεται σε αποτυχία στο errno των υποκείμενων shmat / memcpy / shmdt.

  • Δεν διαβάζονται ούτε εγγράφονται άλλες ειδικές μεταβλητές. Σε αντίθεση με την shmread, η shmwrite δεν μολύνει με taint τίποτα - είναι η πηγή των bytes, όχι αποδέκτης.

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

Δημοσιεύστε εγγραφή σταθερού μεγέθους στην αρχή ενός τμήματος:

use IPC::SysV qw(IPC_PRIVATE S_IRUSR S_IWUSR);
my $id = shmget(IPC_PRIVATE, 4096, S_IRUSR | S_IWUSR)
    or die "shmget: $!";
shmwrite($id, "hello, world", 0, 4096)
    or die "shmwrite: $!";

Ένα STRING κοντύτερο από το SIZE συμπληρώνεται με NUL ώστε να γεμίσει το παράθυρο - χρήσιμο για να καθαρίζετε ξεπερασμένα τελικά bytes από προηγούμενο εγγραφέα:

shmwrite($id, "short", 0, 64);   # 5 bytes of "short", then 59 NULs

Ένα STRING μακρύτερο από το SIZE περικόπτεται· η ουρά απορρίπτεται σιωπηρά, οπότε διαστασιολογήστε το παράθυρό σας στη μεγαλύτερη εγγραφή που σκοπεύετε ποτέ να δημοσιεύσετε:

shmwrite($id, "x" x 10_000, 0, 128);   # only the first 128 x's land

Η εγγραφή σε μη μηδενική μετατόπιση επιτρέπει σε πολλαπλές εγγραφές σταθερού μεγέθους να μοιράζονται ένα τμήμα. Ζευγαρώστε την με αντίστοιχη shmread στην πλευρά του αναγνώστη:

my $slot = 3;
my $len  = 64;
shmwrite($id, $record, $slot * $len, $len)
    or die "shmwrite slot $slot: $!";

Ελέγξτε την τιμή επιστροφής - ένα τμήμα που έχει σημανθεί προς διαγραφή με IPC_RMID εξακολουθεί να δέχεται εγγραφές από διεργασίες ήδη προσαρτημένες, αλλά αποτυγχάνει σε νέες κλήσεις shmwrite με EIDRM:

unless (shmwrite($id, $msg, 0, $SIZE)) {
    warn "segment $id gone: $!";
    # reacquire via shmget() and retry
}

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

  • Ο πυρήνας πρέπει να έχει χτιστεί με SysV IPC. Σε συστήματα χωρίς κοινή μνήμη SysV η shmwrite κράζει με shmwrite not implemented. Αυτή είναι ιδιότητα κατά τη μεταγλώττιση του πυρήνα / libc, όχι συνθήκη χρόνου εκτέλεσης που μπορείτε να ανιχνεύσετε.

  • Το SIZE ίσο με 0 γίνεται αποδεκτό από τον πυρήνα και δεν εγγράφει τίποτα· η shmwrite επιστρέφει αληθές. Χρησιμοποιήστε το μόνο όταν εννοείτε πραγματικά «no-op», όχι ως σήμα σφάλματος.

  • Το POS + SIZE πρέπει να χωράει μέσα στο τμήμα. Η υπέρβαση του ορίου τμήματος αποτυγχάνει με EINVAL και αφήνει το τμήμα ανέγγιχτο - η αντιγραφή δεν είναι μερική.

  • Τα δυαδικά ωφέλιμα φορτία είναι εντάξει. Το STRING αντιμετωπίζεται ως συμβολοσειρά bytes· τα ενσωματωμένα NUL εγγράφονται κυριολεκτικά. Αν η συμβολοσειρά φέρει τη σημαία UTF-8, τα ακατέργαστα εσωτερικά bytes είναι αυτά που φτάνουν στο τμήμα - χρησιμοποιήστε pack ή Encode::encode πρώτα αν χρειάζεστε συγκεκριμένη κωδικοποίηση στο καλώδιο.

  • Καμία κλείδωση. Ο πυρήνας εγγυάται ότι κάθε κλήση shmwrite είναι ατομική ως προς τις shmat / shmdt, αλλά δύο ταυτόχρονοι εγγραφείς μπορούν ακόμη να μπλέξουν εύρη bytes μέσα στο τμήμα. Συντονιστείτε με semop ή κλείδωμα χώρου χρήστη αν πολλαπλές διεργασίες γράφουν στην ίδια περιοχή.

  • Τα δικαιώματα προέρχονται από το mode του τμήματος τη στιγμή της shmget. Προσάρτηση μόνο για ανάγνωση και κλήση shmwrite αποτυγχάνει με EACCES.

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

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

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

  • shmread - αντίστροφη πράξη· αντιγράφει bytes έξω από τμήμα σε βαθμωτό Perl

  • shmget - λαμβάνει το ID στο οποίο γράφει η shmwrite

  • shmctl - επιθεωρεί χαρακτηριστικά τμήματος, αλλάζει δικαιώματα ή σημαίνει τμήμα προς διαγραφή

  • semop - η συνήθης συνοδευτική πρωτογενής για σειριοποίηση πρόσβασης σε κοινό τμήμα

  • pack - δομεί τη συμβολοσειρά bytes σταθερής διάταξης που δίνετε στην shmwrite όταν το τμήμα κρατά δομημένες εγγραφές

  • IPC::SysV - σταθερές (IPC_PRIVATE, S_IRUSR, IPC_RMID) που χρησιμοποιούνται για τη δόμηση των ορισμάτων στις shmget και shmctl