getpriority, setpriority -
プログラムのスケジューリングの優先度を取得/設定する
#include <sys/time.h>
#include <sys/resource.h>
int getpriority(int which, int who);
int setpriority(int which, int who, int
prio );
システムコール
getpriority()
や
setpriority() は、
which と
who
で指定されたプロセス、プロセスグループ、ユーザーの
スケジューリング優先度
(scheduling priority) の
取得や設定をそれぞれ行う。
which の値は
PRIO_PROCESS,
PRIO_PGRP,
PRIO_USER,
のどれか一つで、
who
は
which
に応じて解釈される (
PRIO_PROCESS
だとプロセス識別子、
PRIO_PGRP
だとプロセスグループ識別子、
PRIO_USER だと UID (ユーザID)
と解釈される)。
who
がゼロならば、(それぞれ)呼び出したプロセス、
呼び出したプロセスのプロセスグループ、
呼び出したプロセスの実UID
を意味する。
prio は -20
から 19 の範囲の値で
(但し以下の注意の項を参照のこと)、
デフォルトの優先度は
0 である;
小さな数字ほど、有利なスケジューリングとなる。
getpriority()
コールは指定したプロセスの中の最も高い優先度
(数値的には最小の値)
を返す。
setpriority()
コールは指定したプロセス全ての優先度を指定した値に設定する。
優先度を今より小さい値に設定できるのはスーパーユーザーだけである。
返り値¶
getpriority()
は成功した場合にも -1
の値を返す可能性があるので、
呼び出しの前に外部変数の
errno
をクリアし、呼び出しの後に返り値の
-1 が正当な値か
エラーかを判別する必要がある。
setpriority()
コールはエラーがなければ
0
を返し、エラーがあれば
-1 を返す。
エラー¶
- EINVAL
- which が PRIO_PROCESS,
PRIO_PGRP, PRIO_USER
のいずれでもない。
- ESRCH
- which と who
で指定されたプロセスが存在しない。
上記のものに加えて
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>
で定義されている)。
関連項目¶
nice(1),
renice(1),
fork(2),
capabilities(7)
(Linux 2.6.23 以降の)
カーネルのソースツリー内の
Documentation/scheduler/sched-nice-design.txt
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。