setpgrp#
קובע את קבוצת התהליכים של תהליך.
setpgrp מעביר את התהליך המזוהה על־ידי PID לקבוצת התהליכים המזוהה על־ידי PGRP. PID של 0 משמעו התהליך הנוכחי; PGRP של 0 משמעו ״השתמשו ב־PID כמזהה הקבוצה החדש״ - כלומר, הפכו את התהליך למנהיג קבוצה. ללא ארגומנטים ברירת המחדל היא setpgrp(0, 0), מה שהופך את התהליך הנוכחי למנהיג של קבוצת תהליכים חדשה שמזהה שלה שווה ל־pid שלו עצמו.
זה הממשק של Perl לקריאת המערכת הבסיסית setpgid(2) / setpgrp(2). זוהי אבן הבניין להפרדת תהליך מהטרמינל השולט בו ולסכמות בקרת־job הרוצות לשלוח אותות לקבוצה שלמה בבת־אחת עם kill.
תקציר#
setpgrp PID, PGRP
setpgrp # same as setpgrp(0, 0)
מה מקבלים בחזרה#
1 בהצלחה, undef בכישלון עם $! שנקבע לסיבה (בדרך כלל EPERM כאשר תהליך היעד אינו הקורא או ילד של הקורא, או ESRCH כאשר אין תהליך כזה). בדקו את ערך־ההחזרה - להמשיך בשקט עם תהליך שעדיין בקבוצה הישנה הוא כמעט אף פעם לא מה שרציתם.
setpgrp(0, 0)
or die "setpgrp failed: $!";
מצב גלובלי שהוא נוגע בו#
$!- נקבע לערך ה־errnoבכישלון. אינו נוגע בהצלחה.
דוגמאות#
הפרדת התהליך הנוכחי לקבוצת תהליכים חדשה משלו. זהו הצעד הראשון הקלאסי של רצף ה־daemonisation, מורץ לאחר fork ולפני סגירת המטפלים הסטנדרטיים:
setpgrp(0, 0)
or die "setpgrp failed: $!";
העברת ילד שנוצר זה עתה לקבוצה משלו כך ש־SIGTERM הנשלח לקבוצה הורג את הילד וכל הנכדים שהוא יוצר, מבלי לגעת בהורה:
my $pid = fork // die "fork: $!";
if ($pid == 0) {
setpgrp(0, 0) or die "setpgrp: $!";
exec @cmd or die "exec: $!";
}
# parent: signal the whole group with a negative pid
kill 'TERM', -$pid;
קריאת מזהה הקבוצה בחזרה לאחר קביעתו, באמצעות getpgrp:
setpgrp(0, 0) or die $!;
my $pgid = getpgrp(0);
print "now leader of group $pgid\n";
טיפול במצב כישלון הפורטביליות - בפלטפורמה ללא קריאת המערכת הבסיסית, הפונקציה מעלה חריגה במקום להחזיר undef:
eval { setpgrp(0, 0) };
if ($@) {
warn "no process-group support on this platform: $@";
}
מקרי קצה#
ללא ארגומנטים ברירת המחדל היא
(0, 0). כתיבתsetpgrp;זהה ל־setpgrp(0, 0)- הפיכת התהליך הנוכחי למנהיג קבוצה חדש. הצורה ללא־ארגומנט היא הצורה הפורטבילית (ראו להלן).תאימות BSD 4.2. ה־
setpgrpההיסטורי של BSD 4.2 לא קיבל ארגומנטים. סקריפטים שחייבים לרוץ במערכות כאלה יכולים להסתמך רק על הצורותsetpgrp(0, 0)/setpgrp(); כל צירוף ארגומנטים אחר אינו פורטבילי.מעלה, לא מחזיר
undef, בפלטפורמות לא־נתמכות. במכונה שאינה מיישמת את POSIXsetpgid(2)ואינה את BSDsetpgrp(2),setpgrpמעלה חריגה. זה מצב הכישלון היחיד שאינו עובר דרך$!- עטפו ב־evalאם אתם צריכים להידרדר בחן.EPERMבמעברים חוצי־סשנים. הקרנל דוחה ניסיונות להעביר תהליך לקבוצה בסשן אחר, או להעביר תהליך שכבר קרא ל־exec. תפסו$!== EPERMוחזרו לחלופה במקום לנסות שוב.שליחת אות לקבוצה כולה. ברגע שקבוצה הוקמה,
kill SIG, -$pgidמספק אתSIGלכל תהליך בקבוצה. מוסכמת ה־pid השלילי היא תכונה שלkill, לא שלsetpgrp- אך זו הסיבה שבדרך כלל קוראים ל־setpgrpמלכתחילה.לא מנהיג סשן.
setpgrpמשנה קבוצת תהליכים, לא סשן. כדי להתנתק לחלוטין מהטרמינל השולט אתם זקוקים ל־POSIX::setsid, אשר יוצרת סשן חדש וקבוצה חדשה בצעד אחד.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
getpgrp- קורא את מזהה קבוצת התהליכים הנוכחי; המלווה הברור לאימות שקריאתsetpgrpנכנסה לתוקףPOSIX::setpgid- העטיפה ששמה לפי POSIX סביב אותה קריאת מערכת, מועדפת בקוד חדש מכיוון שסדר הארגומנטים והסמנטיקה שלה חד־משמעיים בכל הפלטפורמותPOSIX::setsid- יוצר סשן חדש וקבוצת תהליכים חדשה בקריאה אחת; השתמשו בזה, לא ב־setpgrp, להפרדה מלאה מהטרמינלfork- הקריאה שכמעט תמיד מקדימה אתsetpgrp; ילד הרוצה קבוצה משלו קורא ל־setpgrp(0, 0)מיד לאחר ש־forkמחזיר0kill- כיצד אתם בעצם משתמשים בקבוצת תהליכים ברגע שבניתם אחת:kill SIG, -$pgidשולח אות לכל חבר