Processes

setpriority#

Set the scheduling priority (nice value) of a process, process group, or user.

setpriority is the Perl-level wrapper around the setpriority(2) system call. WHICH selects the target class (PRIO_PROCESS, PRIO_PGRP, or PRIO_USER), WHO names the specific target within that class (0 means “self” or “current” depending on WHICH), and PRIORITY is the new nice value. Higher values mean lower scheduling priority; on Linux the useful range is -20 (most favourable) through 19 (least favourable).

Synopsis#

setpriority WHICH, WHO, PRIORITY

What you get back#

Returns true on success, undef on failure (with $! set to the underlying errno). The most common failures are EACCES or EPERM — lowering the nice value below the current one, or touching another user’s processes, requires privilege. Always check the return value when the priority change is not just cosmetic:

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

Global state it touches#

  • $! — set on failure to the errno from the underlying setpriority(2) call.

The three WHICH classes#

WHICH is one of three integer constants, each selecting a different interpretation of WHO:

  • PRIO_PROCESSWHO is a process ID. 0 means the current process.

  • PRIO_PGRPWHO is a process group ID. 0 means the process group of the current process.

  • PRIO_USERWHO is a numeric user ID (UID). 0 means the real UID of the current process. Setting by user changes the priority of every process owned by that user.

These constants are not built in — import them from POSIX:

use POSIX qw(PRIO_PROCESS PRIO_PGRP PRIO_USER);

Examples#

Renice the current process to 10 (friendlier to other work):

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

Renice a child process after 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 every process in the current process group — useful in a session leader that wants its whole pipeline to yield:

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

Pair with getpriority to adjust relative to the current value rather than setting an absolute one:

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

Edge cases#

  • Negative priorities require privilege. Lowering the nice value (more favourable scheduling) below the current one needs CAP_SYS_NICE on Linux, or root. An unprivileged attempt fails with EACCES or EPERM depending on kernel version.

  • Nice values are clamped. The kernel silently clamps PRIORITY to the supported range (-20..19 on Linux). Passing 100 does not fail; it ends up as 19.

  • WHO = 0 is context-sensitive. Its meaning depends on WHICH: current PID for PRIO_PROCESS, current process group for PRIO_PGRP, real UID for PRIO_USER. It is not a universal “self” token.

  • Non-existent target. A PID, PGID, or UID that does not match any running process fails with ESRCH.

  • Platform without setpriority(2). Perl raises a fatal exception (setpriority() not implemented). pperl targets Linux only, so this case does not arise in practice, but portable code should still guard with eval.

  • Signed return from getpriority vs. success of setpriority. getpriority can legitimately return -1 as a nice value, which is why it sets $! to distinguish error from result; setpriority has no such ambiguity — treat its return purely as a boolean.

  • Nice value is per-process, not per-thread. On Linux this differs from POSIX: the kernel applies the nice value to the calling task (thread). Perl is single-threaded at the interpreter level, so this only matters if XS code has spawned kernel threads.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • getpriority — read the current nice value; the natural counterpart when adjusting relative to the existing priority

  • POSIX — source of the PRIO_PROCESS, PRIO_PGRP, and PRIO_USER constants

  • fork — typical pairing: spawn a child, then renice it before exec

  • $! — holds the errno describing why a failed setpriority call returned undef

  • kill — other per-process control operation with the same “target by PID or PGID” convention