Jak uruchomić program z polityką SCHED_RR z wiersza poleceń?

11

Domyślnie programy działają w systemie Linux z funkcją Time Sharing (TS policy). Jak uruchomić program z polityką SCHED_RR w systemie Linux z wiersza poleceń?

Dziękujemy za podanie informacji o poleceniu chrt (1). Użyłem tego polecenia, aby uruchomić Firefox z polityką RR, ale jak widać poniżej, tylko główny wątek Firefox działa z polityką RR. Czy możesz mi powiedzieć, jak uruchamiać wszystkie inne wątki Firefoksa, również z zasadami RR.

$ 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

Edycja: Uruchomiłem następujący prosty program pthreads i przetestowałem jak wyżej. Niestety polecenie chrt zmienia tylko klasę głównego wątku. Patrz poniżej.

$ 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);
}
samarasa
źródło

Odpowiedzi:

10

Użyj chrtpolecenia za pomocąchrt --rr <priority between 1-99> <command>

Przykład:

chrt --rr 99 ls

Zauważ, że ustawienie SCHED_RRwymaga uprawnień roota, więc musisz być rootem lub uruchomić go z sudo.

Możesz także użyć, chrtaby nadać działającemu procesowi priorytet w czasie rzeczywistym:

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

Te same polecenia dotyczą również innych klas planowania, aczkolwiek z innym parametrem zamiast -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)

Edytować:

W przypadku Firefoksa musi być specyficzny dla Firefoksa. W aplikacji wielowątkowej, którą sam napisałem, wszystkie wątki zachowują klasę RR. Jak widać w danych wyjściowych, dwa wątki mają klasę RR, więc nie jest to również wątek nadrzędny.

Edycja 2:

Spróbuj rozpocząć proces chrtod zmiany harmonogramu istniejącego pid. Wygląda na to, że jeśli zostaniesz przełożony, tylko pierwszy wątek otrzyma klasę RR. Jeśli jednak zaczniesz chrt, każdy wątek to otrzyma.

Egil
źródło
Dzięki @Egil. Nawiasem mówiąc, domyślną klasą planowania jest prawo TS. Możesz zobaczyć w wynikach polecenia ps.
samarasa
Tak ... działa w ten sposób. Tak, to nie działa, jeśli damy pid.
samarasa
jest ich za mało -r(używane tylko dwa razy), sugeruję użycie -rrrrrrrrrzamiast tego ;-P
poige
Nie musiałem uruchamiać roota po mojej stronie ...
enigmatyczny
@samarasa: może - potrzebujesz opcji. Z instrukcji:-a, --all-tasks Set or retrieve the scheduling attributes of all the tasks (threads) for a given PID.
Narcolessico,
0

Po prostu dodaj ten kod do kodu wątku:

  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);

To da każdemu wątkowi maksymalny priorytet RR.

Zibri
źródło