Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       pthread_setschedparam,  pthread_getschedparam  - スレッドの スケジューリングポリシーとパラ
       メーターを設定/取得する

書式

       #include <pthread.h>

       int pthread_setschedparam(pthread_t thread, int policy,
                                 const struct sched_param *param);
       int pthread_getschedparam(pthread_t thread, int *policy,
                                 struct sched_param *param);

       -pthread でコンパイルしてリンクする。

説明

       pthread_setschedparam() 関数は、スレッド thread の  スケジューリングポリシーとスケジューリ
       ングパラメーターを設定する。

       policythread の新しいスケジューリングポリシーを指定する。 policy に指定できる値とその
       意味は sched(7) で説明されている。

       param が指す構造体は thread の新しいスケジューリングパラメーターを  指定する。スケジューリ
       ングパラメーターは以下の構造体で管理される。

           struct sched_param {
               int sched_priority;     /* Scheduling priority */
           };

       見て分かる通り、サポートされているスケジューリングパラメーターは一つだけである。各スケ
       ジューリングポリシーで許可されるスケジューリング優先度の詳細については、sched(7)  を参照の
       こと。

       pthread_getschedparam()  関数は、スレッド thread の スケジューリングポリシーとパラメーター
       を、 それぞれ policyparam が指すバッファーに入れて返す。  返された優先度の値は、最も最
       近実行した    thread    に影響を与える    pthread_setschedparam(),   pthread_setschedprio,
       pthread_create で設定された値となる。 返された優先度は、優先度の継承や優先度の上限を設定す
       る関数  (例えば pthread_mutexattr_setprioceiling(3) や pthread_mutexattr_setprotocol(3) を
       参照) の呼び出しの結果 行われる一時的な優先度の調整の影響を受けない。

返り値

       成功すると、これらの関数は    0    を返す。    エラーの場合、0    以外のエラー番号を返す。
       pthread_setschedparam()  が失敗した場合、 thread の スケジューリングポリシーとパラメーター
       は変更されない。

エラー

       これらの関数はどちらも以下のエラーで失敗する場合がある。

       ESRCH  ID が thread のスレッドが見つからなかった。

       pthread_setschedparam() はさらに以下のエラーで失敗する場合がある。

       EINVAL policy が認識できないポリシーであるか、 parampolicy  では意味を持たない値であ
              る。

       EPERM  呼び出し側が、指定されたスケジューリングポリシーやパラメーターを設定する のに必要な
              特権を持たない。

       POSIX.1 では、 pthread_setschedparam() に関して エラー ENOTSUP  ("サポートされていない値を
       スケジューリングポリシーや パラメーターに設定しようとした") も追加で規定されている。

属性

       この節で使用されている用語の説明については、 attributes(7) を参照。

       ┌─────────────────────────┬───────────────┬─────────┐
       │インターフェース属性      │
       ├─────────────────────────┼───────────────┼─────────┤
       │pthread_setschedparam(), │ Thread safety │ MT-Safe │
       │pthread_getschedparam()  │               │         │
       └─────────────────────────┴───────────────┴─────────┘

準拠

       POSIX.1-2001, POSIX.1-2008.

注意

       スレッドのスケジューリングポリシーや優先度を変更するために必要な許可や変更した場合の影
       響、および各スケジューリングポリシーで認められる優先度の範囲の詳細については、 sched(7) を
       参照。

       以下のプログラムは pthread_setschedparam() と pthread_getschedparam() やスケジューリングに
       関連する pthreads の 他のいろいろな関数の使用例を示すものである。

       以下の実行例では、メインスレッドは、自分のスケジューリングポリシーを    優先度    10    の
       SCHED_FIFO を設定し、スレッド属性オブジェクトを スケジューリングポリシー属性 SCHED_RR とス
       ケジューリング優先度       属性       20       で初期化する。       次に、このプログラムは
       (pthread_attr_setinheritsched(3)    を使って)    そのスレッド属性オブジェクトの    inherit
       scheduler 属性に PTHREAD_EXPLICIT_SCHED を設定する。PTHREAD_EXPLICIT_SCHED は、 そのスレッ
       ド属性オブジェクトを使って作成されたスレッドはスレッド属性  オブジェクトからスケジューリン
       グ属性を取得して使うことを意味する。  それから、このスレッド属性オブジェクトを使ってスレッ
       ドを作成し、 作成したスレッドのスケジューリングポリシーと優先度を表示する。

           $ su      # Need privilege to set real-time scheduling policies
           Password:
           # ./a.out -mf10 -ar20 -i e
           Scheduler settings of main thread
               policy=SCHED_FIFO, priority=10

           Scheduler settings in 'attr'
               policy=SCHED_RR, priority=20
               inheritsched is EXPLICIT

           Scheduler attributes of new thread
               policy=SCHED_RR, priority=20

       上記の出力では、スケジューリングポリシーと優先度がスレッド属性  オブジェクトで指定された値
       から取られていることが分かる。

       次の実行例は前のものと同じだが、 inherit scheduler 属性が PTHREAD_INHERIT_SCHED に設定され
       る点が異なる。 PTHREAD_INHERIT_SCHED は、そのスレッド属性オブジェクトを使って作成 されたス
       レッドは、スレッド属性オブジェクトからスケジューリング属性を  無視し、代わりに呼び出したス
       レッドからスケジューリング属性を取得する ことを意味する。

           # ./a.out -mf10 -ar20 -i i
           Scheduler settings of main thread
               policy=SCHED_FIFO, priority=10

           Scheduler settings in 'attr'
               policy=SCHED_RR, priority=20
               inheritsched is INHERIT

           Scheduler attributes of new thread
               policy=SCHED_FIFO, priority=10

       上記の出力では、スケジューリングポリシーと優先度が、    スレッド属性オブジェクトからではな
       く、 スレッドを作成したスレッドから取れれていることが分かる。

       なお、 -i i を省略した場合でも、 PTHREAD_INHERIT_SCHED が inherit scheduler 属性のデフォル
       ト値なので、 出力は同じになる。

   プログラムのソース

       /* pthreads_sched_test.c */

       #include <pthread.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <errno.h>

       #define handle_error_en(en, msg) \
               do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

       static void
       usage(char *prog_name, char *msg)
       {
           if (msg != NULL)
               fputs(msg, stderr);

           fprintf(stderr, "Usage: %s [options]\n", prog_name);
           fprintf(stderr, "Options are:\n");
       #define fpe(msg) fprintf(stderr, "\t%s", msg);          /* Shorter */
           fpe("-a<policy><prio> Set scheduling policy and priority in\n");
           fpe("                 thread attributes object\n");
           fpe("                 <policy> can be\n");
           fpe("                     f  SCHED_FIFO\n");
           fpe("                     r  SCHED_RR\n");
           fpe("                     o  SCHED_OTHER\n");
           fpe("-A               Use default thread attributes object\n");
           fpe("-i {e|i}         Set inherit scheduler attribute to\n");
           fpe("                 'explicit' or 'inherit'\n");
           fpe("-m<policy><prio> Set scheduling policy and priority on\n");
           fpe("                 main thread before pthread_create() call\n");
           exit(EXIT_FAILURE);
       }

       static int
       get_policy(char p, int *policy)
       {
           switch (p) {
           case 'f': *policy = SCHED_FIFO;     return 1;
           case 'r': *policy = SCHED_RR;       return 1;
           case 'o': *policy = SCHED_OTHER;    return 1;
           default:  return 0;
           }
       }

       static void
       display_sched_attr(int policy, struct sched_param *param)
       {
           printf("    policy=%s, priority=%d\n",
                   (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                   (policy == SCHED_RR)    ? "SCHED_RR" :
                   (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                   "???",
                   param->sched_priority);
       }

       static void
       display_thread_sched_attr(char *msg)
       {
           int policy, s;
           struct sched_param param;

           s = pthread_getschedparam(pthread_self(), &policy, &param);
           if (s != 0)
               handle_error_en(s, "pthread_getschedparam");

           printf("%s\n", msg);
           display_sched_attr(policy, &param);
       }

       static void *
       thread_start(void *arg)
       {
           display_thread_sched_attr("Scheduler attributes of new thread");

           return NULL;
       }

       int
       main(int argc, char *argv[])
       {
           int s, opt, inheritsched, use_null_attrib, policy;
           pthread_t thread;
           pthread_attr_t attr;
           pthread_attr_t *attrp;
           char *attr_sched_str, *main_sched_str, *inheritsched_str;
           struct sched_param param;

           /* Process command-line options */

           use_null_attrib = 0;
           attr_sched_str = NULL;
           main_sched_str = NULL;
           inheritsched_str = NULL;

           while ((opt = getopt(argc, argv, "a:Ai:m:")) != -1) {
               switch (opt) {
               case 'a': attr_sched_str = optarg;      break;
               case 'A': use_null_attrib = 1;          break;
               case 'i': inheritsched_str = optarg;    break;
               case 'm': main_sched_str = optarg;      break;
               default:  usage(argv[0], "Unrecognized option\n");
               }
           }

           if (use_null_attrib &&
                   (inheritsched_str != NULL || attr_sched_str != NULL))
               usage(argv[0], "Can't specify -A with -i or -a\n");

           /* Optionally set scheduling attributes of main thread,
              and display the attributes */

           if (main_sched_str != NULL) {
               if (!get_policy(main_sched_str[0], &policy))
                   usage(argv[0], "Bad policy for main thread (-m)\n");
               param.sched_priority = strtol(&main_sched_str[1], NULL, 0);

               s = pthread_setschedparam(pthread_self(), policy, &param);
               if (s != 0)
                   handle_error_en(s, "pthread_setschedparam");
           }

           display_thread_sched_attr("Scheduler settings of main thread");
           printf("\n");

           /* Initialize thread attributes object according to options */

           attrp = NULL;

           if (!use_null_attrib) {
               s = pthread_attr_init(&attr);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_init");
               attrp = &attr;
           }

           if (inheritsched_str != NULL) {
               if (inheritsched_str[0] == 'e')
                   inheritsched = PTHREAD_EXPLICIT_SCHED;
               else if (inheritsched_str[0] == 'i')
                   inheritsched = PTHREAD_INHERIT_SCHED;
               else
                   usage(argv[0], "Value for -i must be 'e' or 'i'\n");

               s = pthread_attr_setinheritsched(&attr, inheritsched);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_setinheritsched");
           }

           if (attr_sched_str != NULL) {
               if (!get_policy(attr_sched_str[0], &policy))
                   usage(argv[0],
                           "Bad policy for 'attr' (-a)\n");
               param.sched_priority = strtol(&attr_sched_str[1], NULL, 0);

               s = pthread_attr_setschedpolicy(&attr, policy);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_setschedpolicy");
               s = pthread_attr_setschedparam(&attr, &param);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_setschedparam");
           }

           /* If we initialized a thread attributes object, display
              the scheduling attributes that were set in the object */

           if (attrp != NULL) {
               s = pthread_attr_getschedparam(&attr, &param);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_getschedparam");
               s = pthread_attr_getschedpolicy(&attr, &policy);
               if (s != 0)
                   handle_error_en(s, "pthread_attr_getschedpolicy");

               printf("Scheduler settings in 'attr'\n");
               display_sched_attr(policy, &param);

               s = pthread_attr_getinheritsched(&attr, &inheritsched);
               printf("    inheritsched is %s\n",
                       (inheritsched == PTHREAD_INHERIT_SCHED)  ? "INHERIT" :
                       (inheritsched == PTHREAD_EXPLICIT_SCHED) ? "EXPLICIT" :
                       "???");
               printf("\n");
           }

           /* Create a thread that will display its scheduling attributes */

           s = pthread_create(&thread, attrp, &thread_start, NULL);
           if (s != 0)
               handle_error_en(s, "pthread_create");

           /* Destroy unneeded thread attributes object */

           if (!use_null_attrib) {
             s = pthread_attr_destroy(&attr);
             if (s != 0)
                 handle_error_en(s, "pthread_attr_destroy");
           }

           s = pthread_join(thread, NULL);
           if (s != 0)
               handle_error_en(s, "pthread_join");

           exit(EXIT_SUCCESS);
       }

関連項目

       getrlimit(2), sched_get_priority_min(2), pthread_attr_init(3),
       pthread_attr_setinheritsched(3), pthread_attr_setschedparam(3),
       pthread_attr_setschedpolicy(3), pthread_create(3), pthread_self(3),
       pthread_setschedprio(3), pthreads(7), sched(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。