shmwrite#
מעתיק בתים לתוך מקטע זיכרון משותף של System V.
shmwrite מתחבר למקטע הזיכרון המשותף המזוהה על־ידי ID, מעתיק עד SIZE בתים מ־STRING החל ב־offset הבתים POS בתוך המקטע, ומתנתק. אם STRING ארוך מ־SIZE, רק SIZE הבתים הראשונים נכתבים; אם הוא קצר יותר, יתרת חלון ה־SIZE בתים מולאית באפסים בבתי NUL. ה־ID של המקטע הוא הערך המוחזר על־ידי קריאת shmget קודמת (או מתקבל מתהליך אחר דרך ערוץ חוץ־רצועה כלשהו).
תקציר#
shmwrite ID, STRING, POS, SIZE
מה מקבלים בחזרה#
אמת בהצלחה, שקר בשגיאה, עם $! שנקבע לסיבה (בדרך כלל EINVAL, EACCES, או EIDRM). בשונה מרוב פונקציות I/O המובנות, ערך־ההחזרה הוא בוליאני רגיל - אין וריאנט של ספירת בתים, מכיוון שהספירה תמיד בדיוק SIZE כשהקריאה מצליחה.
shmwrite($id, $payload, 0, 4096)
or die "shmwrite($id) failed: $!";
מצב גלובלי שהוא נוגע בו#
דוגמאות#
פרסום רשומה בגודל קבוע בתחילת מקטע:
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 למילוי החלון - שימושי לניקוי בתים מיושנים נסחבים מכותב קודם:
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
כתיבה ל־offset לא־אפס מאפשרת למספר רשומות בגודל קבוע לחלוק מקטע אחד. שייכו אותה עם 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מטופל כמחרוזת בתים; NULים מוטמעים נכתבים מילולית. אם המחרוזת נושאת את דגל ה־UTF-8, הבתים הפנימיים הגולמיים הם מה שמגיע למקטע - השתמשו ב־packאוEncode::encodeתחילה אם אתם צריכים קידוד ספציפי על החוט.אין נעילה. הקרנל מבטיח שכל קריאת
shmwriteהיא אטומית ביחס ל־shmat/shmdt, אך שני כותבים בו־זמניים עדיין יכולים לשלב טווחי בתים בתוך המקטע. תאמו עםsemopאו מנעול במרחב משתמש אם מספר תהליכים כותבים לאותו אזור.הרשאות מגיעות ממצב המקטע בזמן
shmget. חיבור לקריאה־בלבד וקריאה ל־shmwriteנכשלת עםEACCES.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
shmread- פעולה הפוכה; מעתיק בתים מתוך מקטע אל סקלר של Perlshmget- משיג את ה־IDש־shmwriteכותב אליוshmctl- בוחן תכונות מקטע, משנה הרשאות, או מסמן מקטע למחיקהsemop- הפרימיטיב המלווה הרגיל לסריאליזציה של גישה למקטע משותףpack- בונה את מחרוזת הבתים בעלת המבנה הקבוע שאתם מוסרים ל־shmwriteכשהמקטע מכיל רשומות מובנותIPC::SysV- קבועים (IPC_PRIVATE,S_IRUSR,IPC_RMID) שמשמשים לבניית הארגומנטים ל־shmgetו־shmctl