תהליכים

setpriority#

מגדיר את עדיפות התזמון (ערך nice) של תהליך, קבוצת תהליכים, או משתמש.

setpriority הוא העטיפה ברמת Perl סביב קריאת המערכת setpriority(2). WHICH בוחר את מחלקת היעד (PRIO_PROCESS, PRIO_PGRP, או PRIO_USER), WHO שם את היעד הספציפי בתוך אותה מחלקה (0 משמעו ״עצמי״ או ״נוכחי״ בתלות ב־WHICH), ו־PRIORITY הוא ערך ה־nice החדש. ערכים גבוהים יותר משמעם עדיפות תזמון נמוכה יותר; ב־Linux הטווח השימושי הוא -20 (הכי מועדף) עד 19 (הכי פחות מועדף).

תקציר#

setpriority WHICH, WHO, PRIORITY

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

מחזיר אמת בהצלחה, undef בכישלון (כאשר $! מוגדר ל־errno הבסיסי). הכישלונות הנפוצים ביותר הם EACCES או EPERM - הורדת ערך ה־nice מתחת לערך הנוכחי, או נגיעה בתהליכים של משתמש אחר, דורשת הרשאה. תמיד בדקו את ערך ההחזרה כאשר שינוי העדיפות אינו רק קוסמטי:

setpriority(PRIO_PROCESS, $$, 10)
    or die "cannot renice self: $!";

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

  • $! - מוגדר בכישלון ל־errno מקריאת setpriority(2) הבסיסית.

שלוש מחלקות WHICH#

WHICH הוא אחד משלושה קבועים שלמים, כל אחד בוחר פרשנות שונה של WHO:

  • PRIO_PROCESS - WHO הוא מזהה תהליך. 0 משמעו התהליך הנוכחי.

  • PRIO_PGRP - WHO הוא מזהה קבוצת תהליכים. 0 משמעו קבוצת התהליכים של התהליך הנוכחי.

  • PRIO_USER - WHO הוא מזהה משתמש מספרי (UID). 0 משמעו ה־UID האמיתי של התהליך הנוכחי. הגדרה לפי משתמש משנה את העדיפות של כל תהליך בבעלות אותו משתמש.

הקבועים האלה אינם מובנים - ייבאו אותם מ־POSIX:

use POSIX qw(PRIO_PROCESS PRIO_PGRP PRIO_USER);

דוגמאות#

Renice של התהליך הנוכחי ל־10 (ידידותי יותר לעבודה אחרת):

use POSIX qw(PRIO_PROCESS);
setpriority(PRIO_PROCESS, 0, 10)
    or die "renice failed: $!";

Renice של תהליך־ילד לאחר fork:

use POSIX qw(PRIO_PROCESS);
my $pid = fork // die "fork: $!";
if ($pid == 0) {
    setpriority(PRIO_PROCESS, $$, 15);  # child runs at low priority
    exec @cmd;
}

Renice של כל תהליך בקבוצת התהליכים הנוכחית - שימושי במנהיג סשן שרוצה שכל השרשרת שלו תוותר:

use POSIX qw(PRIO_PGRP);
setpriority(PRIO_PGRP, 0, 5)
    or warn "could not renice process group: $!";

שילוב עם getpriority להתאמה יחסית לערך הנוכחי במקום הגדרת ערך מוחלט:

use POSIX qw(PRIO_PROCESS);
my $cur = getpriority(PRIO_PROCESS, 0);
setpriority(PRIO_PROCESS, 0, $cur + 5)
    or die "renice failed: $!";

מקרי קצה#

  • עדיפויות שליליות דורשות הרשאה. הורדת ערך ה־nice (תזמון מועדף יותר) מתחת לערך הנוכחי דורשת CAP_SYS_NICE ב־Linux, או root. ניסיון לא־מורשה נכשל עם EACCES או EPERM בהתאם לגרסת הקרנל.

  • ערכי nice נחתכים. הקרנל חותך בשקט את PRIORITY לטווח הנתמך (-20..19 ב־Linux). העברת 100 אינה נכשלת; היא מסתיימת כ־19.

  • WHO = 0 רגיש להקשר. משמעותו תלויה ב־WHICH: PID נוכחי עבור PRIO_PROCESS, קבוצת תהליכים נוכחית עבור PRIO_PGRP, UID אמיתי עבור PRIO_USER. הוא אינו טוקן ״עצמי״ אוניברסלי.

  • יעד שאינו קיים. PID, PGID, או UID שאינו תואם לאף תהליך רץ נכשל עם ESRCH.

  • פלטפורמה ללא setpriority(2). Perl מעלה חריגה קטלנית (setpriority() not implemented). pperl מכוון ל־Linux בלבד, אז המקרה הזה אינו עולה בפועל, אך קוד נייד עדיין צריך לשמור עם eval.

  • החזרה חתומה מ־getpriority לעומת הצלחת setpriority. getpriority יכול להחזיר באופן חוקי -1 כערך nice, ולכן הוא מגדיר את $! כדי להבחין בין שגיאה לתוצאה; ל־setpriority אין דו־משמעות כזו - התייחסו להחזרה שלו רק כאל ערך בוליאני.

  • ערך nice הוא לכל־תהליך, לא לכל־thread. ב־Linux זה שונה מ־POSIX: הקרנל מחיל את ערך ה־nice על המשימה הקוראת (thread). Perl הוא חד־thread ברמת המפרש, אז זה משנה רק אם קוד XS הריץ threadים של קרנל.

הבדלים מהמקור#

תאימות מלאה עם Perl 5.42 המקורי.

ראו גם#

  • getpriority - קריאת ערך ה־nice הנוכחי; המקבילה הטבעית בעת התאמה יחסית לעדיפות הקיימת

  • POSIX - מקור הקבועים PRIO_PROCESS, PRIO_PGRP, ו־PRIO_USER

  • fork - שילוב טיפוסי: הפעלת ילד, ואז renice אותו לפני exec

  • $! - מחזיק את ה־errno המתאר מדוע קריאת setpriority שנכשלה החזירה undef

  • kill - פעולת בקרה אחרת לכל־תהליך עם אותה מוסכמת ״יעד לפי PID או PGID״