sched_setscheduler(2)
๐ sched_setscheduler(2) โ the sched_setscheduler / sched_getscheduler girlies ๐
okay bestie, pull up a chair, because today we're talking about the system calls that decide which thread gets to run and how it gets to run. these live in section 2 of the manual (system calls, iykyk), and they are literally the main character energy of the Linux scheduler. ๐
โจ NAME โจ
<pink>sched_setscheduler</pink>, <pink>sched_getscheduler</pink> โ set and get scheduling policy/parameters. slay, that's the whole job. ๐
๐ธ LIBRARY ๐ธ
Standard C library (<purple>libc</purple>, <purple>-lc</purple>)
โจ SYNOPSIS โจ
#include <sched.h>
int sched_setscheduler(pid_t pid, int policy,
const struct sched_param *param);
int sched_getscheduler(pid_t pid);
๐ฆ DESCRIPTION ๐ฆ
so. the <cyan>sched_setscheduler()</cyan> system call is the one that sets both the scheduling policy and the parameters for the thread whose ID you pass in as pid. multitasking queen. ๐
and if pid equals zero? cute. then it sets the scheduling policy and parameters of the calling thread itself. self-care. ๐ธ
the scheduling parameters go in the param argument, which is a pointer to a structure shaped like this:
struct sched_param {
...
int sched_priority;
...
};
ngl, in the current implementation the structure contains only one field, <purple>sched_priority</purple>. and the way param gets interpreted totally depends on the policy you picked. like, it's giving "context matters." ๐
๐ the "normal" (i.e., non-real-time) policies ๐
currently, Linux supports the following "normal" โ i.e. non-real-time โ scheduling policies as values you can shove into policy:
<mint>SCHED_OTHER</mint>โ the standard round-robin time-sharing policy. the default bestie, the people's princess. โจ<mint>SCHED_BATCH</mint>โ for "batch" style execution of processes. lowkey efficient. ๐<mint>SCHED_IDLE</mint>โ for running very low priority background jobs. it's giving "no thoughts, head empty, run whenever." ๐
for each of the policies above, param->sched_priority must be 0. no exceptions, bestie. ๐จ
๐ฅ the "real-time" policies ๐ฅ
various "real-time" policies are also supported, for special time-critical applications that need precise control over the way runnable threads get selected for execution. this is the VIP section, no cap. ๐
for the rules governing when a process may use these policies, go see <purple>sched(7)</purple>. the real-time policies you can specify in policy are:
<hotpink>SCHED_FIFO</hotpink>โ a first-in, first-out policy; and<hotpink>SCHED_RR</hotpink>โ a round-robin policy.
for each of the above, param->sched_priority specifies a scheduling priority for the thread. ๐ this is a number in the range returned by calling <purple>sched_get_priority_min(2)</purple> and <purple>sched_get_priority_max(2)</purple> with the specified policy. and on Linux? those two system calls return, respectively, <yellow>1</yellow> and <yellow>99</yellow>. periodt. ๐
โจ the SCHED_RESET_ON_FORK moment โจ
since Linux <yellow>2.6.32</yellow>, the <mint>SCHED_RESET_ON_FORK</mint> flag can be ORed in policy when you call sched_setscheduler(). what does including this flag do? children created by <purple>fork(2)</purple> do not inherit privileged scheduling policies. iconic behaviour tbh. see <purple>sched(7)</purple> for the details. ๐ซถ
๐ and now, sched_getscheduler() ๐
<cyan>sched_getscheduler()</cyan> returns the current scheduling policy of the thread identified by pid. and yep โ if pid equals zero, the policy of the calling thread will be retrieved. it's the same trick, just backwards. ๐ฆ
โญ RETURN VALUE โญ
- on success,
<cyan>sched_setscheduler()</cyan>returns<yellow>zero</yellow>. ๐ - on success,
<cyan>sched_getscheduler()</cyan>returns the policy for the thread (a nonnegative integer). โจ - on error, both calls return
<red>-1</red>, and<purple>errno</purple>is set to indicate the error. ๐ญ
๐ ERRORS ๐
EINVALโ Invalid arguments:pidis negative orparamisNULL. ๐EINVALโ (sched_setscheduler())policyis not one of the recognized policies. like, be serious. ๐EINVALโ (sched_setscheduler())paramdoes not make sense for the specified policy. mismatch energy fr fr. ๐ซEPERMโ The calling thread does not have appropriate privileges. girl, you don't have clearance for this VIP section. ๐ESRCHโ The thread whose ID ispidcould not be found. she's not here, bestie. ๐
๐ VERSIONS ๐
POSIX.1 does not detail the permissions that an unprivileged thread requires in order to call <cyan>sched_setscheduler()</cyan>, and the details vary across systems. it's giving "every OS has its own rules." for example, the Solaris 7 manual page says that the real or effective user ID of the caller must match the real user ID or the save set-user-ID of the target. ngl, the drama.
the scheduling policy and parameters are in fact per-thread attributes on Linux. ๐ง that means:
- the value returned from a call to
<purple>gettid(2)</purple>can be passed in the argumentpid. - specifying
pidas<yellow>0</yellow>will operate on the attributes of the calling thread. - passing the value returned from a call to
<purple>getpid(2)</purple>will operate on the attributes of the main thread of the thread group.
(if you are using the POSIX threads API, then use<purple>pthread_setschedparam(3)</purple>,<purple>pthread_getschedparam(3)</purple>, and<purple>pthread_setschedprio(3)</purple>, instead of thesched_*(2)system calls. that's the assigned reading, bestie. ๐)
๐ธ STANDARDS ๐ธ
<mint>POSIX.1-2024</mint> (but see BUGS below ๐).
<mint>SCHED_BATCH</mint> and <mint>SCHED_IDLE</mint> are Linux-specific. ๐
๐ HISTORY ๐
<mint>POSIX.1-2001</mint>. classic. vintage. we love an OG.
โญ NOTES โญ
further details of the semantics of all of the above "normal" and "real-time" scheduling policies can be found in the <purple>sched(7)</purple> manual page. that page also describes an additional policy, <hotpink>SCHED_DEADLINE</hotpink>, which is settable only via <purple>sched_setattr(2)</purple>. exclusive fr. ๐ฅ
POSIX systems on which <cyan>sched_setscheduler()</cyan> and <cyan>sched_getscheduler()</cyan> are available define <purple>_POSIX_PRIORITY_SCHEDULING</purple> in <purple><unistd.h></purple>. check for it, bestie. ๐ฆ
๐จ BUGS ๐จ
okay this is the unhinged part. POSIX.1 says that on success, sched_setscheduler() should return the previous scheduling policy. but Linux sched_setscheduler() does not conform to this requirement โ because it always returns <yellow>0</yellow> on success. ๐ she simply refuses. that's the tea.
๐ SEE ALSO ๐
<purple>chrt(1)</purple>, <purple>nice(2)</purple>, <purple>sched_get_priority_max(2)</purple>, <purple>sched_get_priority_min(2)</purple>, <purple>sched_getaffinity(2)</purple>, <purple>sched_getattr(2)</purple>, <purple>sched_getparam(2)</purple>, <purple>sched_rr_get_interval(2)</purple>, <purple>sched_setaffinity(2)</purple>, <purple>sched_setattr(2)</purple>, <purple>sched_setparam(2)</purple>, <purple>sched_yield(2)</purple>, <purple>setpriority(2)</purple>, <purple>capabilities(7)</purple>, <purple>cpuset(7)</purple>, <purple>sched(7)</purple>
and that's the whole page, bestie!! ๐ซถโจ this little love letter is from Linux man-pages 6.20, dated 2026-02-08 โ shoutout to the man-pages girlies for keeping section 2 so cunty. now go set some priorities (responsibly!!). ๐ ๐๐
๐ฆ where this page comes from
- arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- ๐ the page's license: Linux-man-pages-copyleft
- Copyright 2014, Michael Kerrisk <mtk.manpages@gmail.com>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms