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: pid is negative or param is NULL. ๐Ÿ™ˆ
  • EINVAL โ€” (sched_setscheduler()) policy is not one of the recognized policies. like, be serious. ๐Ÿ’…
  • EINVAL โ€” (sched_setscheduler()) param does 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 is pid could 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 argument pid.
  • specifying pid as <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 the sched_*(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
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms