msgget#
יוצר או מחפש תור הודעות של System V IPC ומחזיר את ה־id שלו.
msgget הוא נקודת הכניסה למשפחת תורי ההודעות של System V: כל קריאת msgsnd, msgrcv, או msgctl מאוחרת זקוקה ל־id, ומכאן ה־id הזה מגיע. KEY מנקב את התור על פני המערכת כולה (מספר שלם key_t, נבנה בדרך כלל עם IPC::SysV::ftok או הערך המיוחד IPC_PRIVATE). FLAGS הוא bitwise-or של ביטי הרשאות (התשעה הנמוכים, פריסה זהה למצבי קבצים) ודגלים אופציונליים 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 הוא ידית אטומה - אל תבצע חשבון עליו, פשוט העבר אותו בחזרה למובנים האחרים 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.ביטי הרשאות חלים בכל קריאה, לא רק ביצירה. חיבור לתור קיים ללא
IPC_CREATעדיין בודק את ביטי ההרשאות מול הבעלים/קבוצה של התור ו־uid/gid האפקטיביים של התהליך הנוכחי. ביטים לא־תואמים נותניםEACCES.IPC_EXCLללאIPC_CREATהוא חסר־משמעות - הקרנל מתעלם ממנו. אם אתה רוצה יצירה בלעדית, תמיד התאם ביניהם.מגבלות כלל־מערכת. יצירה יכולה להיכשל עם
ENOSPCכאשר נוגעים במגבלתMSGMNIשל הקרנל, אוENOMEMתחת לחץ זיכרון. אלה אינם באגים בתוכנית שלך; אלה תנאי הפעלה.משך חיי התור עולה על חיי תהליכים. תור שנוצר כאן מתמיד עד הסרה מפורשת עם
msgctlו־IPC_RMID, או עד שהמערכת מבצעת אתחול. תורים נשכחים מדלפים משאבי קרנל ש־ipcsו־ipcrmמשמשים למצוא ולנקות.לא לכל המערכות יש תורי הודעות SysV. בפלטפורמות המשמיטות אותם, המובנה עושה croak עם
msgget not implemented on this architecture. אזהרת הניידות ב־POD המקורי חלה.
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
msgsnd- שולח הודעה לתור שמחזירmsggetmsgrcv- מקבל הודעה מאותו תורmsgctl- מתשאל, מגדיר אפשרויות, או מסיר את התור; הפירוק לאחרmsggetעובר כאןsemget- אותה צורת API לסמפורי System V כשאתה צריך סנכרון במקום העברת נתוניםshmget- אותה צורת API לזיכרון משותף של System V כשאתה צריך שיתוף זיכרון ישיר במקום העברת הודעותIPC::SysV- מספק אתftokואת הקבועיםIPC_*/S_*ש־msggetמצפה להם ב־FLAGS