תהליכים

getpgrp#

מחזיר את מזהה קבוצת־התהליכים של POSIX שאליו שייך תהליך.

כל תהליך Unix הוא חבר בדיוק בקבוצת תהליכים אחת, אשר בתורה שייכת לסשן. קבוצות תהליכים הן הדרך שבה הקרנל מתייחס לתהליכים קשורים כיחידה - באופן הגלוי ביותר, הן היחידה שמקבלת אות מהטרמינל השולט (SIGINT בלחיצת Ctrl-C, SIGTSTP בלחיצת Ctrl-Z). getpgrp מבקש מהקרנל את מזהה הקבוצה של תהליך נתון; ללא ארגומנט או עם PID של 0 הוא משיב עבור התהליך הנוכחי.

תקציר#

getpgrp
getpgrp PID
getpgrp 0

מה מקבלים בחזרה#

מספר שלם אי־שלילי - מזהה קבוצת־התהליכים בהקשר סקלר. מזהי קבוצות־תהליכים משתפים את מרחב המספור של PID, ו־PID של מנהיג הקבוצה שווה למזהה הקבוצה, כך שהערך שמוחזר על־ידי getpgrp 0 הוא ה־PID של מנהיג הקבוצה של התהליך הנוכחי.

במערכת שאינה מיישמת את getpgrp(2) כלל, הקריאה מעלה חריגה קטלנית. זה נדיר ביותר ב־Unix מודרני; Linux, ה־BSD־ים, macOS ו־Solaris כולם תומכים בה.

מצב גלובלי שהוא נוגע בו#

אין. getpgrp קורא מצב קרנל עבור התהליך הנקוב וקובע את $! רק בכישלון (אשר, במערכת POSIX, משמעו ״אין תהליך כזה״ עבור PID שאינו אפס שאינו קיים).

דוגמאות#

קבלת הקבוצה של התהליך הנוכחי עצמו:

my $pgid = getpgrp;
print "my group is $pgid\n";

PID של 0 משמעו ״עצמי״ והוא הצורה הפורטבילית - מערכות ישנות מאוד מסוימות אינן מקבלות שום ערך אחר:

my $pgid = getpgrp 0;                 # same as getpgrp with no args

לזהות האם התהליך הנוכחי הוא מנהיג הקבוצה של עצמו - הבדיקה הרגילה ש־daemon מבצע לפני קריאה ל־setpgrp או POSIX::setsid כדי להתנתק מהטרמינל השולט בו:

if (getpgrp(0) == $$) {
    print "already a group leader\n";
}
else {
    print "group leader is ", getpgrp(0), "\n";
}

חיפוש הקבוצה של תהליך אחר, למשל ילד שזה עתה הוחזר על־ידי fork:

my $pid = fork // die "fork: $!";
if ($pid == 0) {
    # child
    exec @cmd;
}
print "child $pid is in group ", getpgrp($pid), "\n";

שליחת אות לכל חבר בקבוצת תהליכים. kill עם PID שלילי מכוון לקבוצה, ו־getpgrp הוא הדרך לגלות את מזהה הקבוצה לשם שלילתו:

my $grp = getpgrp($child);
kill 'TERM', -$grp;                   # SIGTERM to the whole group

מקרי קצה#

  • ארגומנט מושמט שווה ל־PID של 0: getpgrp ו־getpgrp 0 שניהם מדווחים על הקבוצה של התהליך הנוכחי. העדיפו את הצורה המפורשת של 0 כשפורטביליות למערכות היסטוריות חשובה.

  • PID לא־קיים: מחזיר undef וקובע את $! ל־"No such process" (ESRCH). בדקו את $!, לא את אמיתיות ערך־ההחזרה - מזהה קבוצה לגיטימי של 0 הוא שקר ב־Perl אך אינו מצב שגיאה (ב־Linux, זוהי קבוצת idle/swapper).

  • חיפושים לא־מורשים: במערכות המגבילות חיפושים חוצי־סשנים, תשאול PID בסשן אחר עלול להיכשל עם $! שנקבע ל־"Operation not permitted" (EPERM). זה בלתי־רגיל ב־Linux, היכן שכל תהליך רשאי לתשאל את הקבוצה של כל PID.

  • getpgrp מול getpgrp PID: הצורה החד־ארגומנטית בסגנון BSD לא הייתה פורטבילית לכל Unixים היסטורית; POSIX סיפק את שתיהן. בפלטפורמות ש־pperl רץ עליהן (Linux, כל יעדי cranelift), שתי הצורות פועלות.

  • עם סימן מול ללא סימן: טיפוס ה־PID של הקרנל הוא עם סימן, ולכן הערך המוחזר נכנס בנוחות במספר שלם של Perl. החזרה של -1 אינה משמשת להצלחה בשום פלטפורמת יעד של pperl; התייחסו ל־-1 כסנטינל שגיאה רק אם אתם מעבירים קוד מבסיס־קוד C שבדק כך.

  • אינו alias של shell עבור בקרת job: הסימון jobs ו־% של ה־shell פועלים על טבלאות job שה־shell שומר, לא על קבוצות תהליכי הקרנל ישירות. getpgrp מספר לכם את אמת הקרנל, אשר עלולה להיסחף מתפיסת ה־job tree של תת־shell.

הבדלים מ־upstream#

תואם מלא ל־upstream Perl 5.42.

ראו גם#

  • setpgrp - שם תהליך לקבוצה חדשה או קיימת; המקבילה של כתיבה ל־getpgrp

  • getppid - מזהה תהליך־האב; לעיתים קרובות רצוי לצד מזהה הקבוצה במהלך הליכה על יחסי תהליכים

  • getpriority - קורא קדימות תזמון, אשר מקבל גם בורר קבוצת־תהליכים (PRIO_PGRP)

  • fork - הילד נירש את קבוצת התהליכים של הוריו, כך ש־getpgrp על ילד טרי מדווח על קבוצת ההורה עד שקריאת setpgrp משנה אותה

  • kill - kill SIGNAL, -$pgid שולח אות לכל חבר בקבוצה; getpgrp הוא הדרך למצוא את $pgid

  • $$ - ה־PID הנוכחי; שווה ל־getpgrp(0) כאשר התהליך הוא מנהיג הקבוצה של עצמו