65558
Linux(CentOS7)のプログラムを練習しています。

sched_setscheduler() システムコールで自プロセスのスケジューリングポリシーを SCHED_RR
に変更し、同時に優先度を設定するように引数を設定しました。このときの優先度は10を設定したとします。

```

      //優先度を設定する その1
      policy_param.sched_priority = priority; //値の例:10
      //タスクスケジューリングポリシーをRRに変更と同時に優先度を設定
      policy_result = sched_setscheduler(0, SCHED_RR, &policy_param);
    
```

ところが、その後getpriority()にて実際の優先度を調べてみると、値が0となっており、優先度の設定が効いていないようです。

```

      printf("実際の優先度: %d\n", getpriority(PRIO_PROCESS, 0));
    
```

```

    実際の優先度: 0
    
```

その後、setpriority()にて優先度を設定すると、優先度が変化します。

```

      //優先度を設定する その2
      priority_result = setpriority(PRIO_PROCESS, getpid(), priority);
    
```

```

      printf("実際の優先度: %d\n", getpriority(PRIO_PROCESS, 0));
    
```

```

    実際の優先度: 10
    
```

最初の sched_setscheduler() でスケジューリングポリシーと同時に優先度を設定したときに、これが反映されないのはなぜでしょうか。  
ご教示いただけると幸いです。

使用しているソースコードの全文と、実行例を下記に添付します。

* * *

・ソースコード

```

    //priority_calc1.c
    /*
    モンテカルロ法による計算でで円周率を求める。
    スケジューリングポリシーをラウンドロビン方式に変更する。
    優先度と計算時間を引数にとり、計算パフォーマンスを表示する。
    */
    
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sched.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    
    #include <unistd.h>
    #include <errno.h>  
    
    
    //２つの時刻の時間差を計算する
    double timeDiff(struct timespec startTime, struct timespec endTime){
      double time;
    
      if (endTime.tv_nsec < startTime.tv_nsec) {
        time = endTime.tv_sec - startTime.tv_sec - 1;
        time += (endTime.tv_nsec + 1000000000 - startTime.tv_nsec) / 1000000000.0;
      } else {
        time = endTime.tv_sec - startTime.tv_sec;
        time += (endTime.tv_nsec - startTime.tv_nsec) / 1000000000.0;
      }
    
      return(time);
    
    }
    
    //現在の時間を取得する
    struct timespec getTime(void){
      struct timespec time;
    
      clock_gettime(CLOCK_REALTIME, &time);
    
      return(time);
    }
    
    
    //モンテカルロ法で円周率を計算する
    double calc_pi_monte(int calc_count){
      int i;
      static double hit = 0.0;
      static double x,y;
      static double distance;
      static double pi = 123;
      static double total_calc_count = 0;
    
      // 乱数の種を初期化
      srand(time(NULL));
    
      //0 〜 1 の乱数を生成・出力
      for(i=0; i < calc_count; i++){
       x = (double) rand() / RAND_MAX;
       y = (double) rand() / RAND_MAX;
       distance = x*x + y*y;
    
       //半径1の円の中に収まっていれば
       if( distance < 1 ){
         hit += 1.0;
       }
    
       total_calc_count += 1;
    
       //円周率を計算・出力
       pi = (double)hit / total_calc_count * 4;
      }
    
      return(pi);
    }
    
    
    
    int main(int argc, char *argv[]) {
      struct timespec start_time, now_time;
      double pi_monte;
      double process_time;
      double process_time_max = 1.0;
    
      int ret_nice;
    
      int calc_count = 0;
    
      int calc_time;
    
      struct sched_param policy_param;
      int policy_result;
      int priority_result;
    
      int priority;
      int priority_max, priority_min;
    
    
    
      if(argc != 3){
        fprintf(stderr, "./priority_calc1 優先度 計算時間(秒)\n");
        exit(1);
      }
    
      sscanf(argv[1], "%d"  ,&priority);
      sscanf(argv[2], "%lf" ,&process_time_max);
    
      //優先順位の範囲を取得
      priority_min = sched_get_priority_min(SCHED_RR);
      priority_max = sched_get_priority_max(SCHED_RR);
    
     //優先度の指定が範囲内でないとき
     if( (priority < priority_min) || (priority > priority_max) ){
        fprintf(stderr, "PRIORITY: %d - %d\n", priority_min, priority_max);
        exit(1);
      }
    
      //優先度を設定する その1
      policy_param.sched_priority = priority;
    
    
      //タスクスケジューリングポリシーをRRに変更と同時に優先度を設定
      policy_result = sched_setscheduler(0, SCHED_RR, &policy_param);
    
      if(policy_result == -1){
        perror("sched_setscheduler error: ");
        exit(1);
      }
    
      //優先度を設定する その2
      //priority_result = setpriority(PRIO_PROCESS, getpid(), priority);
    
      if(priority_result == -1){
        perror("setpriority error: ");
        exit(1);
      }
    
    
      //計算開始前の時刻を取得
      start_time = getTime();
    
      printf("計算を開始します...\n");
      printf("優先度指定: %d\n", priority);
      printf("計算時間指定: %f\n", process_time_max);
      printf("\n....");
    
      do{
    
        pi_monte = calc_pi_monte(1000);
    
        //現在の時刻を取得
        now_time = getTime();
    
        //開始から経過した時間を計算
        process_time = timeDiff(start_time, now_time);
        calc_count ++;
      } while(process_time <= process_time_max);
    
    
    
      printf("\n");
      printf("計算が終了しました\n");
      printf("実際の優先度: %d\n", getpriority(PRIO_PROCESS, 0));
      printf("実際の経過実時間 = %f\n", process_time);
    
      printf("求めた円周率: %f\n", pi_monte);
      printf("計算できた回数(ループ数): %d\n", calc_count);
      printf("1秒あたりの計算回数(ループ数): %f\n\n", calc_count / process_time);
    
      return 0;
    }
    
    
```

・実行例 その１(ソースコードをそのまま実行、優先順位指定が反映されない)

```

    $ sudo ./priority_calc1 20 10
    計算を開始します...
    優先度指定: 20
    計算時間指定: 10.000000
    
    ....
    計算が終了しました
    実際の優先度: 0
    実際の経過実時間 = 10.000002
    求めた円周率: 3.148555
    計算できた回数(ループ数): 565261
    1秒あたりの計算回数(ループ数): 56526.088033
    
```

・実行例 その２(//優先度を設定する その2 のコメントアウトを取りsetpriority()を実行)

```

    $ sudo ./priority_calc1 20 10
    計算を開始します...
    優先度指定: 20
    計算時間指定: 10.000000
    
    ....
    計算が終了しました
    実際の優先度: 19
    実際の経過実時間 = 10.000011
    求めた円周率: 3.158527
    計算できた回数(ループ数): 573755
    1秒あたりの計算回数(ループ数): 57375.438407
    
    
```
CC BY-SA 4.0
2020-04-06T07:34:35.193
65394
2020-04-12T10:30:17.387
2020-04-06T07:40:19.740
38053
38053
question
linux c centos
sched_setscheduler() で SCHED_RR を指定したときに sched_priority の優先度が反映されない
プロセスは大きく「通常」と「リアルタイム」に区分され、通常プロセス間の優先度を決める数値がnice値で、リアルタイムプロセスの優先度とは別のものになります。

`getpriority`と`setpriority`はnice値の取得・操作です。

`sched_setscheduler`で`SCHED_RR`を指定するとそのプロセスはリアルタイムプロセスとなり優先度は`sched_param::sched_priority`になります。

[Man page of SCHED](https://linuxjm.osdn.jp/html/LDP_man-
pages/man7/sched.7.html)に詳しい説明があります。
CC BY-SA 4.0
2020-04-12T10:30:17.387
65558
2020-04-12T10:30:17.387
4388
65394
answer