setpriority(2) プログラムのスケジューリングの優先度を取得/設定する

Other Alias

getpriority

書式

#include <sys/time.h>
#include <sys/resource.h>

int getpriority(int which, int who);
int setpriority(int which, int who, int prio);

説明

システムコール getpriority() や setpriority() は、 whichwho で指定されたプロセス、プロセスグループ、ユーザーの スケジューリング優先度 (scheduling priority) の 取得や設定をそれぞれ行う。

which の値は PRIO_PROCESS, PRIO_PGRP, PRIO_USER, のどれか一つで、 whowhich に応じて解釈される (PRIO_PROCESS だとプロセス識別子、 PRIO_PGRP だとプロセスグループ識別子、 PRIO_USER だと UID (ユーザID) と解釈される)。 who がゼロならば、(それぞれ)呼び出したプロセス、 呼び出したプロセスのプロセスグループ、 呼び出したプロセスの実UID を意味する。 prio は -20 から 19 の範囲の値で (但し以下の注意の項を参照のこと)、 デフォルトの優先度は 0 である; 小さな数字ほど、有利なスケジューリングとなる。

getpriority() コールは指定したプロセスの中の最も高い優先度 (数値的には最小の値) を返す。 setpriority() コールは指定したプロセス全ての優先度を指定した値に設定する。 優先度を今より小さい値に設定できるのはスーパーユーザーだけである。

返り値

getpriority() は成功した場合にも -1 の値を返す可能性があるので、 呼び出しの前に外部変数の errno をクリアし、呼び出しの後に返り値の -1 が正当な値か エラーかを判別する必要がある。 setpriority() コールはエラーがなければ 0 を返し、エラーがあれば -1 を返す。

エラー

EINVAL
whichPRIO_PROCESS, PRIO_PGRP, PRIO_USER のいずれでもない。
ESRCH
whichwho で指定されたプロセスが存在しない。

上記のものに加えて setpriority() では以下のエラーがある:

EACCES
呼び出し元がプロセスの優先度を下げようとしたが、必要な特権を 持っていなかった (Linux の場合、 CAP_SYS_NICE ケーパビリティがなかった)。 Linux 2.6.12 以降では、呼び出し元が、あるプロセスの優先度を、 変更対象のプロセスのリソース RLIMIT_NICE のソフトリミットの範囲外に設定しようとした場合にのみ、 このエラーが発生する。詳細は getrlimit(2) を参照。
EPERM
プロセスは見つかったが、そのプロセスの実効 (effective) UID が 呼び出し元の実効UID にも実 (real) UID にも一致せず、 呼び出し元が特権も持っていなかった (Linux の場合、 CAP_SYS_NICE ケーパビリティがなかった)。 以下の「注意」も参照のこと。

準拠

SVr4, 4.4BSD (これらの関数は 4.2BSD で最初に登場した), POSIX.1-2001.

注意

fork(2) で作成された子プロセスは、 親プロセスの nice 値を継承する。 execve(2) の前後で nice 値は保存される。

相対的な nice 値の違いがプロセス間のスケジューリングにどの程度影響を与えるか は、UNIX システム間で異なり、Linux ではカーネルバージョンにより異なる。 Linux は、カーネル 2.6.23 以降で、nice 値の相対的な違いが、非常に強い影響を 与えるアルゴリズムを採用した。このアルゴリズムでは、 他に優先度の高いものがシステムに存在する時には、 非常に低い nice 値 (+19) ではプロセスに本当にほとんど CPU が割り当てられない。 また、高い nice 値 (-20) では CPU を必要とするアプリケーション (例えば オーディオアプリケーション) に CPU のほとんどが割り当てられる。

EPERM が発生する条件の詳細はシステムに依存する。 上記の説明は POSIX.1-2001 のものであり、全ての System V 風システムは これに従っているようである。 2.6.12 より前の Linux カーネルでは、呼び出し元の実 UID または 実効 UID がプロセス who の (実効 UID でなく) 実 UID に一致する必要がある。 Linux 2.6.12 以降では、呼び出し元の実行 UID がプロセス who の実 UID か実効 UID のいずれかと一致する必要がある。 全ての BSD 風システム (SunOS 4.1.3, Ultrix 4.2, 4.3BSD, FreeBSD 4.3, OpenBSD-2.5等) は、 Linux 2.6.12 以降と同じ動作をする。

実際の優先度の値の範囲はカーネルのバージョンによって異なる。 1.3.36 より前の Linux では、優先度の範囲は負の無限大 〜 15 である。 1.3.43 以降の Linux では、優先度の範囲は -20 〜 19 である。 カーネル内部では、nice 値は実際には 40 〜 1 の範囲を使って 表現されており (負の値はエラーコードとなるため)、こちらの値が システムコール setpriority() と getpriority() で使用されている。 glibc のこれらのシステムコールのラッパー関数において、nice 値の ユーザ領域 (user-land) とカーネル表現の間の変換が行われる。 変換式は以下の通り: unice = 20 - knice

いくつかのシステムでは、nice 値の範囲は 20 〜 20 である。

現在では <sys/time.h> をインクルードする必要はないが、インクルードすれば移植性を高めることができる (実際には <sys/resource.h>rusage 構造体が定義されているが、そのフィールドで使用されている struct timeval 型は <sys/time.h> で定義されている)。

バグ

POSIX では nice 値はプロセス単位の設定となっている。 一方、 現在の POSIX スレッドの Linux/NPTL 実装では、 nice 値はスレッド単位の属性である。 同じプロセスの別々のスレッドが異なる nice 値を持つ場合がある。 移植性が必要なアプリケーションではこの Linux の動作を前提するのは避けるべきである。 Linux の動作は将来標準に準拠した動作になるかもしれない。

この文書について

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