Διεργασίες

setpriority#

Ορίζει την προτεραιότητα χρονοπρογραμματισμού (nice value) μιας διεργασίας, ομάδας διεργασιών, ή χρήστη.

Η setpriority είναι το περιτύλιγμα σε επίπεδο Perl γύρω από την κλήση συστήματος setpriority(2). Το WHICH επιλέγει την κλάση στόχου (PRIO_PROCESS, PRIO_PGRP, ή PRIO_USER), το WHO κατονομάζει τον συγκεκριμένο στόχο εντός αυτής της κλάσης (το 0 σημαίνει «εαυτός» ή «τρέχων» ανάλογα με το WHICH), και το PRIORITY είναι η νέα nice value. Υψηλότερες τιμές σημαίνουν χαμηλότερη προτεραιότητα χρονοπρογραμματισμού· στο Linux το χρήσιμο εύρος είναι -20 (πιο ευνοϊκή) έως 19 (λιγότερο ευνοϊκή).

Σύνοψη#

setpriority WHICH, WHO, PRIORITY

Τι επιστρέφεται#

Επιστρέφει αληθές σε επιτυχία, undef σε αποτυχία (με το $! ρυθμισμένο στο υποκείμενο errno). Οι συνηθέστερες αποτυχίες είναι EACCES ή EPERM - η μείωση της nice value κάτω από την τρέχουσα, ή το άγγιγμα διεργασιών άλλου χρήστη, απαιτεί προνόμιο. Ελέγχετε πάντα την τιμή επιστροφής όταν η αλλαγή προτεραιότητας δεν είναι απλώς αισθητική:

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

Καθολική κατάσταση που επηρεάζει#

  • $! - τίθεται σε αποτυχία στο errno της υποκείμενης κλήσης setpriority(2).

Οι τρεις κλάσεις WHICH#

Το WHICH είναι μία από τρεις ακέραιες σταθερές, καθεμία επιλέγει διαφορετική ερμηνεία του WHO:

  • PRIO_PROCESS - το WHO είναι ID διεργασίας. Το 0 σημαίνει την τρέχουσα διεργασία.

  • PRIO_PGRP - το WHO είναι ID ομάδας διεργασιών. Το 0 σημαίνει την ομάδα διεργασιών της τρέχουσας διεργασίας.

  • PRIO_USER - το WHO είναι αριθμητικό ID χρήστη (UID). Το 0 σημαίνει το πραγματικό UID της τρέχουσας διεργασίας. Ο ορισμός κατά χρήστη αλλάζει την προτεραιότητα κάθε διεργασίας που ανήκει σε αυτόν τον χρήστη.

Αυτές οι σταθερές δεν είναι ενσωματωμένες - εισαγάγετέ τες από το POSIX:

use POSIX qw(PRIO_PROCESS PRIO_PGRP PRIO_USER);

Παραδείγματα#

Επαναπροσδιορισμός της nice value της τρέχουσας διεργασίας σε 10 (πιο φιλικό προς άλλη εργασία):

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

Επαναπροσδιορισμός nice value σε διεργασία παιδί μετά από 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;
}

Επαναπροσδιορισμός nice value για κάθε διεργασία στην τρέχουσα ομάδα διεργασιών - χρήσιμο σε επικεφαλής συνεδρίας που θέλει ολόκληρη η pipeline του να παραχωρήσει:

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 value (πιο ευνοϊκός χρονοπρογραμματισμός) κάτω από την τρέχουσα χρειάζεται CAP_SYS_NICE στο Linux, ή root. Μια ανεξουσιοδότητη προσπάθεια αποτυγχάνει με EACCES ή EPERM ανάλογα με την έκδοση του πυρήνα.

  • Οι nice values περικόπτονται. Ο πυρήνας περικόπτει σιωπηλά το 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 value, και γι’ αυτό θέτει το $! για να διακρίνει σφάλμα από αποτέλεσμα· η setpriority δεν έχει τέτοια αμφισημία - αντιμετωπίστε την επιστροφή της καθαρά ως λογική τιμή.

  • Η nice value είναι ανά διεργασία, όχι ανά νήμα. Στο Linux αυτό διαφέρει από το POSIX: ο πυρήνας εφαρμόζει τη nice value στο καλούν task (νήμα). Η Perl είναι μονονηματική σε επίπεδο διερμηνέα, οπότε αυτό έχει σημασία μόνο αν κώδικας XS έχει δημιουργήσει νήματα πυρήνα.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • getpriority - διαβάζει την τρέχουσα nice value· ο φυσικός αντίστοιχος όταν ρυθμίζετε σχετικά ως προς την υπάρχουσα προτεραιότητα

  • POSIX - πηγή των σταθερών PRIO_PROCESS, PRIO_PGRP και PRIO_USER

  • fork - τυπικός συνδυασμός: δημιουργήστε παιδί, και μετά αλλάξτε του τη nice value πριν την exec

  • $! - κρατά το errno που περιγράφει γιατί μια αποτυχημένη κλήση setpriority επέστρεψε undef

  • kill - άλλη πράξη ελέγχου ανά διεργασία με την ίδια σύμβαση «στόχευση κατά PID ή PGID»