11.3. Using Library Calls to Set Priority
The library calls below are used to set the priority of non-realtime processes.
nice
getpriority
setpriority
These functions retrieve and adjust the nice value of a non-realtime process. The nice value serves as a suggestion to the scheduler on how to order the list of ready-to-run non-realtime processes to be run on a processor. The processes at the head of the list run sooner than the ones further back.
Realtime processes use a different set of library calls to control policy and priority, which will be detailed in this section.
Important
The following functions all require the inclusion of the
sched.h
header file. Ensure you always check the return codes from functions. The appropriate man pages outline the various codes used.
11.3.1. sched_getscheduler
The
sched_getscheduler()
function retrieves the scheduler policy for a given PID:
#include <sched.h> int policy; policy = sched_getscheduler(pid_t pid);
The symbols
SCHED_OTHER
, SCHED_RR
and SCHED_FIFO
are also defined in sched.h
. They can be used to check the defined policy or to set the policy:
#include <stdio.h> #include <unistd.h> #include <sched.h> main(int argc, char *argv[]) { pid_t pid; int policy; if (argc < 2) pid = 0; else pid = atoi(argv[1]); printf("Scheduler Policy for PID: %d -> ", pid); policy = sched_getscheduler(pid); switch(policy) { case SCHED_OTHER: printf("SCHED_OTHER\n"); break; case SCHED_RR: printf("SCHED_RR\n"); break; case SCHED_FIFO: printf("SCHED_FIFO\n"); break; default: printf("Unknown...\n"); } }
11.3.2. sched_setscheduler
The scheduler policy and other parameters can be set using the
sched_setscheduler()
function. Currently, realtime policies have one parameter, sched_priority
. This parameter is used to adjust the priority of the process.
The
sched_setscheduler
function requires three parameters, in the form: sched_setscheduler(pid_t pid, int policy, const struct sched_param *sp);
Note
The
sched_setscheduler
(2) man page lists all possible return values of sched_setscheduler
, including the error codes.
If the
pid
is zero, the sched_setscheduler()
function will act on the calling process.
The following code excerpt sets the scheduler policy of the current process to
SCHED_FIFO
and the priority to 50:
struct sched_param sp = { .sched_priority = 50 }; int ret; ret = sched_setscheduler(0, SCHED_FIFO, &sp); if (ret == -1) { perror("sched_setscheduler"); return 1; }
11.3.3. sched_getparam
and sched_setparam
The
sched_setparam()
function is used to set the scheduling parameters of a particular process. This can then be verified using the sched_getparam()
function.
Unlike the
sched_getscheduler()
function, which only returns the scheduling policy, the sched_getparam()
function returns all scheduling parameters for the given process.
The following code excerpt reads the priority of a given realtime process and increments it by two:
struct sched_param sp; int ret; /* reads priority and increments it by 2 */ ret = sched_getparam(0, &sp); sp.sched_priority += 2; /* sets the new priority */ ret = sched_setparam(0, &sp);
Note: If the code above were used in a real application, it would also need to check the return values from the function, and handle any errors appropriately.
Important
Be careful with incrementing priorities. Continually adding two as in this example might eventually lead to an invalid priority.
11.3.4. sched_get_priority_min
and sched_get_priority_max
The
sched_get_priority_min
and sched_get_priority_max
functions are used to check the valid priority range for a given scheduler policy.
The only possible error in this call will occur if the specified scheduler policy is not known by the system. In this case, the function will return
-1
and errno
will be set to EINVAL
:
#include <stdio.h> #include <unistd.h> #include <sched.h> main() { printf("Valid priority range for SCHED_OTHER: %d - %d\n", sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER)); printf("Valid priority range for SCHED_FIFO: %d - %d\n", sched_get_priority_min(SCHED_FIFO), sched_get_priority_max(SCHED_FIFO)); printf("Valid priority range for SCHED_RR: %d - %d\n", sched_get_priority_min(SCHED_RR), sched_get_priority_max(SCHED_RR)); }
Note
Both
SCHED_FIFO
and SCHED_RR
can be any number within the range of 1 to 99. POSIX is not guaranteed to honor this range, however, and portable programs should use these calls.
11.3.5. sched_rr_get_interval
The
SCHED_RR
policy differs slightly from the SCHED_FIFO
policy. SCHED_RR
allocates concurrent processes that have the same priority in a round-robin rotation. In this way, each process is assigned a timeslice. The sched_rr_get_interval()
function will report the timeslice that has been allocated to each process.
Even though POSIX requires that this function must work only with
SCHED_RR
processes, the sched_rr_get_interval()
function is able to retrieve the timeslice length of any process on Linux.
The timeslice information is returned as a
timespec
, or the number of seconds and nanoseconds since the base time of 00:00:00 GMT, 1 January 1970:
struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ }
The
sched_rr_get_interval
function requires the PID of the process, and a struct timespec:
#include <stdio.h> #include <sched.h> main() { struct timespec ts; int ret; /* real apps must check return values */ ret = sched_rr_get_interval(0, &ts); printf("Timeslice: %lu.%lu\n", ts.tv_sec, ts.tv_nsec); }
The following commands run the test program
sched_03
, with varying policies and priorities. Processes with a SCHED_FIFO
policy will return a timeslice of 0 seconds and 0 nanoseconds, indicating that it is infinite:
~]$ chrt -o 0 ./sched_03
Timeslice: 0.38994072
~]$ chrt -r 10 ./sched_03
Timeslice: 0.99984800
~]$ chrt -f 10 ./sched_03
Timeslice: 0.0
Note
For more information, or for further reading, the following man pages are related to the information given in this section:
- nice(2)
- getpriority(2)
- setpriority(2)