תהליכים

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, בפלטפורמות לא־נתמכות. במכונה שאינה מיישמת את POSIX setpgid(2) ואינה את BSD setpgrp(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 מחזיר 0

  • kill - כיצד אתם בעצם משתמשים בקבוצת תהליכים ברגע שבניתם אחת: kill SIG, -$pgid שולח אות לכל חבר