semget#
יצירה או חיפוש של מערכת סמפורים של System V והחזרת המזהה שלה.
semget היא נקודת הכניסה ל־API של סמפורי SysV. היא עוטפת את קריאת המערכת semget(2): בהינתן KEY מספרי שנותן שם למערכת, מספר הסמפורים NSEMS במערכת, ומילת FLAGS המשלבת ביטי הרשאה עם דגלי יצירה, הקרנל מחזיר או את ה־id של מערכת קיימת תואמת, או, אם IPC_CREAT ב־FLAGS, יוצר מערכת חדשה ומחזיר את ה־id שלה. ה־id המוחזר הוא ה־handle שכל קריאת סמפור אחרת (semop, semctl) מצפה לו.
תקציר#
semget KEY, NSEMS, FLAGS
מה מקבלים בחזרה#
מזהה מערכת הסמפורים (מספר שלם אי־שלילי) בהצלחה, או undef בכישלון עם $! שנקבע ל־errno מהקריאה הבסיסית semget(2). ה־id אינו file descriptor - זהו 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)הופך נתיב מערכת קבצים בתוספת בית פרויקט למפתח מספרי. המתכון הסטנדרטי לתהליכים שאינם קשורים הזקוקים להסכים על מפתח ללא קידוד קשיח של מספר קסם.
הארגומנט FLAGS#
FLAGS משלב ביטי הרשאה (9 ביטים נמוכים, כמו mode של chmod: 0600, 0660, 0666) עם דגלי יצירה מ־IPC::SysV:
IPC_CREAT- יצירת המערכת אם היא אינה קיימת כבר. ללא דגל זה,semgetרק מחפש מערכת קיימת עם המפתח הנתון.IPC_CREAT | IPC_EXCL- יצירת המערכת, אבל כישלון עםEEXISTאם אחת כבר קיימת עבורKEY. המקבילה של SysV ל־O_CREAT | O_EXCLב־open.
ביטי הרשאה נבדקים על־ידי הקרנל בכל קריאה עוקבת של 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: $!";
אידיום יצירה־או־פתיחה - לנסות יצירה בלעדית, ולחזור לחיפוש. התהליך הראשון שעובר מאתחל את המערכת; מאוחרים יותר רק מתחברים:
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: ביטי הרשאה חלים. מערכת שנוצרה עם0400היא קריאה־בלבד אפילו לתהליך היוצר עבור קריאותsemopשמשנות אותה.מגבלות קרנל:
semgetיכול להיכשל עםENOSPCכאשר מגבלת מערכות הסמפורים ברמת־המערכת נגמרת, אוEINVALכאשרNSEMSחורג מהמקסימום לכל־מערכת. ראוipcs -slלמגבלות הנוכחיות בלינוקס.Leaked sets: a set persists until
IPC_RMIDor reboot. Long-running daemons that forget to remove their sets accumulate them;ipcs -slists the survivors,ipcrm -s $idremoves one.Key collisions: two unrelated programs picking the same hard-coded
KEYwill see each other’s set - hence theftok(3)idiom.אינו מטפל קובץ:
$semidהוא מספר שלם, לא מטפל. אין להעבירו ל־close,fcntl, או כל פעולת מטפל קובץ.Forks יורשים ids, לא בעלות: ילד רואה את אותו ערך
$semidכמו ההורה ויכול להשתמש בו, אבל המערכת עצמה בבעלות ה־uid שיצר אותה, לא של תהליך מסוים.הקשר מספרי: ה־id הוא מספר שלם פשוט, בטוח להדפסה, השוואה ושמירה בקובץ עבור תהליך אחר שיאסוף.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
semop- ביצוע פעולות wait/signal על המערכת שמוחזרת על־ידיsemgetsemctl- פעולות בקרה על המערכת: אתחול ערכים (SETALL,SETVAL), קריאתם (GETALL,GETVAL), והסרת המערכת (IPC_RMID)msgget- המקבילה של תור־הודעות, אותן מוסכמותKEY, FLAGSshmget- המקבילה של זיכרון משותף, אותן מוסכמותKEY, FLAGSIPC::SysV- מייבא אתIPC_CREAT,IPC_EXCL,IPC_PRIVATE,IPC_RMID,SETALL,GETALL, ואת עוזרftokIPC::Semaphore- עטיפת עצם סביב ה־built-ins הגולמיים שלsem*כאשר מעדיפים לא לארוז structs ביד