14

By default programs run with Time Sharing (TS policy) on Linux. How to run a program with SCHED_RR policy on Linux from command line?

Thanks for giving information about chrt(1) command. I have used the command to run Firefox with RR policy, but as you see below, only main thread of Firefox runs with RR policy. Could you tell me how to run all other threads of Firefox also with RR policy.

$ ps -Lo pid,tid,class 2051
  PID   TID CLS
 2051  2051 RR
 2051  2055 TS
 2051  2056 TS
 2051  2057 TS
 2051  2058 TS
 2051  2059 TS
 2051  2060 TS
 2051  2061 TS
 2051  2063 TS
 2051  2067 TS
 2051  2068 TS
 2051  2069 TS
 2051  2070 TS
 2051  2072 TS
 2051  2073 TS
 2051  2074 TS
 2051  2075 TS
 2051  2077 TS
 2051  2078 TS
 2051  2080 TS
 2051  2356 RR
 2051  2386 TS
 2051  2387 TS

Edit: I ran the following simple pthreads program and tested like the above. Unfortunately chrt command only changes the class of the main thread. Please see below.

$ ps -Lo pid,tid,class 3552
  PID   TID CLS
 3552  3552 TS
 3552  3553 TS
 3552  3554 TS
 3552  3555 TS
 3552  3556 TS
 3552  3557 TS

$ sudo chrt --rr -p 30 3552
 ...
$ ps -Lo pid,tid,class 3552
  PID   TID CLS
 3552  3552 RR
 3552  3553 TS
 3552  3554 TS
 3552  3555 TS
 3552  3556 TS
 3552  3557 TS

---- Program----

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   long k = 1;
   long a[10000];
   int i = 1;
  long b[10000];

   for (k = 0; k < 400000000; k++) {
        if (i == 9999) {
       i = 1;   
    } 
    a[i] = ((k + i) * (k - i))/2;
    a[i] = k/2;
        b[i] = i * 20;
    b[i] = a[i] - b[i];
        i++;
    int j = 0;
    for (j = 0; j < i; j++) {
        k = j - i;  
    } 
     } 
    
   pthread_exit(NULL);
   
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }
   pthread_exit(NULL);
}
Gabriel Staples
  • 8,025
  • 7
  • 66
  • 105
samarasa
  • 4,571
  • 7
  • 31
  • 33
  • For 5 really thorough demos of how to do this in code instead of at the command-line, [see my answer here](https://stackoverflow.com/a/71757858/4561887). More-specifically, see "Demo 1" through "Demo 5" inside function `set_scheduler()` in my **[sleep_nanosleep_minimum_time_interval.c](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/sleep_nanosleep_minimum_time_interval.c)** test file. – Gabriel Staples Apr 08 '22 at 00:07

2 Answers2

15

Use the chrt command with chrt --rr <priority between 1-99> <command>

Example:

# Note: `sudo` is not required if you are root
chrt --rr 99 ls

# use `sudo` otherwise
sudo chrt --rr 99 ls

Note that setting SCHED_RR require root permissions, so you either have to be root or run it with sudo.

You can also use chrt to give a running process realtime priority:

chrt -p --rr <priority between 1-99> <pid>

The same commands applies for other scheduling classes as well, albeit with a different parameter instead of -rr:

Scheduling policies:
  -b | --batch         set policy to SCHED_BATCH
  -f | --fifo          set policy to SCHED_FIFO
  -i | --idle          set policy to SCHED_IDLE
  -o | --other         set policy to SCHED_OTHER
  -r | --rr            set policy to SCHED_RR (default)

Edit:

In the Firefox case, it must be spesific to Firefox. In a multithreaded application I wrote myself, all the threads keep the RR class. As seen in your output, two threads have class RR, so it's not only the parent thread either.

Edit 2:

Try starting the process with chrt instead of rescheduling an existing pid. It appears that if you reschedule, only the first thread gets RR class. However, if you start it with chrt, every thread gets it.

Gabriel Staples
  • 8,025
  • 7
  • 66
  • 105
Egil
  • 14,002
  • 2
  • 45
  • 54
  • Thanks @Egil. By the way, the default scheduking class is TS right. You can see in the ps command output. – samarasa Jun 30 '11 at 17:33
  • Yeah..its working in this way. SOmehow, it is not working if we give pid. – samarasa Jun 30 '11 at 19:53
  • there're too few `-r` (only used twice), I suggest using `-rrrrrrrrr` instead ;-P – poige Sep 02 '17 at 03:23
  • It didn't need root to run on my end... – enigmaticPhysicist Dec 10 '17 at 23:00
  • @samarasa : maybe -a option is what you need. From the manual: `-a, --all-tasks Set or retrieve the scheduling attributes of all the tasks (threads) for a given PID.` – Narcolessico Feb 02 '18 at 09:34
  • Run `chrt --max` to see a list of priority ranges you can specify for each scheduler type. RR shows 1-99: `SCHED_RR min/max priority : 1/99`. Question: which is the _highest_ priority? `1`? Or `99`? – Gabriel Staples Apr 06 '22 at 01:18
  • I did a bunch of research and reading, and found it in multiple places, but I'd like to report back that _for the `SCHED_RR` round-robin policy_ `99` is the _highest_ priority, and `1` is the _lowest_ priority. [Here](https://man7.org/linux/man-pages/man7/sched.7.html) is one of many sources which state this: _"(`SCHED_FIFO`, `SCHED_RR`) have a sched_priority value in the range `1` (low) to `99` (high)."_ – Gabriel Staples Apr 06 '22 at 23:36
  • For anyone who thinks this is obvious, it's not. Many priority systems are inverted. The NVIC (Nested Vector Interrupt Controller), for instance, for ARM-core microcontrollers, is inverted, with `0` being the _highest priority_ and `255` being the _lowest_ priority. [See here](https://developer.arm.com/documentation/ddi0337/e/Exceptions/Exception-priority/Priority-levels#:~:text=Priority%20level%200%20is%20the,level%20255%20is%20the%20lowest.). So, regarding the priority levels of `1` to `99` for the Linux `SCHED_RR` round-robin scheduler, I had to ask. – Gabriel Staples Apr 06 '22 at 23:38
2

Just add this code inside the thread code:

pthread_t this_thread = pthread_self();
struct sched_param params;
params.sched_priority = sched_get_priority_max(SCHED_RR);
pthread_setschedparam(this_thread, SCHED_RR, &params);

This will give the any thread which runs this code the maximum SCHED_RR (round-robin real-time scheduler) priority of 99.

See:

  1. A description of each scheduler policy, including the SCHED_RR round-robin soft real-time scheduler: https://man7.org/linux/man-pages/man7/sched.7.html.
  2. A mention that the min and max priorities for the SCHED_RR scheduler are 1 and 99, respectively: https://man7.org/linux/man-pages/man2/sched_get_priority_min.2.html.
  3. https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html
Gabriel Staples
  • 8,025
  • 7
  • 66
  • 105
Zibri
  • 711
  • 8
  • 8
  • 1
    You may actually want to give the thread the *minimum* `SCHED_RR` priority of `1`, instead of the maximum priority of `99`, in order to ensure that you don't block threads which need to be high priority, such as the network stack. I'm not 100% sure, but I think setting your thread's priority to `99` could block the network stack & result in strange bugs. Using `SCHED_RR` _is_ necessary to get much better timing resolution (**~5 us** sleep resolution vs **55 us sleep resolution**) when using calls such as `clock_nanosleep()`, but using the highest priority within this policy is _not_ required. – Gabriel Staples Apr 06 '22 at 22:07
  • This is another great resource to read to learn about the Linux soft real-time scheduler policies and priorities: [Dr. Dobb's: Soft Real-Time Programming with Linux](https://www.drdobbs.com/soft-real-time-programming-with-linux/184402031). – Gabriel Staples Apr 06 '22 at 22:10
  • 1
    Thanks for your answer here, by the way. It helped me figure out my own answer here: [see my answer here](https://stackoverflow.com/a/71757858/4561887), and I referenced it in making my "Demo 1" through "Demo 5" inside function `set_scheduler()` in my **[sleep_nanosleep_minimum_time_interval.c](https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/sleep_nanosleep_minimum_time_interval.c)** test file. – Gabriel Staples Apr 08 '22 at 00:09