semctl#
ביצוע פעולת בקרה על מערכת סמפורים של System V.
semctl הוא הקישור ברמת Perl לקריאת המערכת semctl(2). הוא קורא או מתקן את מצבה של מערכת הסמפורים המזוהה על־ידי ID - קבלה או קביעה של ערך של סמפור יחיד, שליפה או התקנה של וקטור הערכים המלא, קריאה של מטא־דאטת semid_ds הקשורה, או הסרת המערכת לחלוטין. CMD בוחר את הפעולה; SEMNUM בוחר איזה סמפור בתוך המערכת (מתעלמים ממנו עבור פקודות לכל־המערכת כמו IPC_STAT, IPC_RMID, GETALL, SETALL); ARG הוא ה־buffer של הקלט או הפלט של הפקודה.
semctl היא עטיפה דקה - הסמנטיקה, קבועי הפקודה, וצורת 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:
המחרוזת
"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 הניתן לשינוי (משתנה פשוט, לא ליטרל או ביטוי); בהצלחה ה־buffer נדרס במקום עם הבתים המוחזרים ומבצעים 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: $!";
קריאת כל ערכי הסמפורים בבת־אחת. ה־buffer חייב להיות מוקצה מראש לגודל הנכון - 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 נכתב במקום עם ה־struct הארוז; הפריסה שלו ספציפית־לפלטפורמה, ולכן יש לבצע 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)בתים עבורGETALL, אוsizeof(struct semid_ds)עבורIPC_STAT. העברת buffer קצר יותר היא התנהגות בלתי־מוגדרת בקריאת ה־C הבסיסית;pack("s!*", (0) x $nsems)הוא האידיום הסטנדרטי ל־GETALL.shortמקומי, לאshortנייד. ערכי סמפור הם Cshort(חתום, בדרך־כלל 16־ביט). יש להשתמש ב־s!ב־pack/unpack- ה־!בוחר את הסוג המקומי לפלטפורמה.sפשוט מאלץ little-endian 16־ביט ויפיק תוצאות שגויות במערכות 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 במטמון מעבר להסרה.המערכת היא קרנל־גלובלית ושורדת מעבר ליציאות תהליכים. מערכת שנוצרה על־ידי סקריפט שקרס נשארת עד שמישהו קורא ל־
IPC_RMID(או שהמערכת מבוצעת reboot). יש להשתמש ב־ipcs -s/ipcrm -sמה־shell כדי לבחון או לנקות מערכות שדלפו.הרשאות באות מ־
semget. ה־IPC_CREAT | modeשמועבר בזמן יצירה שולט במי רשאי להוציא איזה פקודותsemctl.EACCESמ־semctlמשמעו שביטי ה־mode אינם מתירים את הפעולה המבוקשת עבור ה־uid האפקטיבי הנוכחי.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
semget- יצירה או חיפוש של מערכת הסמפורים שאת ה־id שלה מעבירים ל־semctlsemop- פעולות ההמתנה / סיגנל בפועל;semctlלבקרה ובחינה,semopעושה את העבודהmsgctl- קריאת הבקרה המקבילה עבור תורי הודעות של System V; אותה מוסכמת ערך־החזרהshmctl- קריאת הבקרה המקבילה עבור זיכרון משותף של System V; אותה מוסכמת ערך־החזרהpack- כיצד לבנות את ה־buffer שלARGעםs!עבור ערכי סמפור ו־struct שלsemid_dsIPC::Semaphore- עטיפת עצם שמסתירה אתsemctlמאחורי מתודות בעלות שם; יש לפנות אליה כאשר סקריפט עושה יותר מקריאה אחת או שתיים