sched_setaffinity - システムコールの説明 - Linux コマンド集 一覧表
名前
sched_setaffinity, sched_getaffinity, CPU_CLR, CPU_ISSET, CPU_SET, CPU_ZERO - プロセスの CPU affinity マスクを設定・取得する
書式
#include <sched.h>
int sched_setaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
int sched_getaffinity(pid_t pid, unsigned int cpusetsize, cpu_set_t *mask);
void CPU_CLR(int cpu, cpu_set_t *set);
int CPU_ISSET(int cpu, cpu_set_t *set);
void CPU_SET(int cpu, cpu_set_t *set);
void CPU_ZERO(cpu_set_t *set);
説明
プロセスの CPU affinity (親和度) マスクは、そのプロセスが
実行を許可されている CPU の集合を決定する。
マルチプロセッサ・システムでは、CPU affinity マスクを設定することで
性能上のメリットを得られる可能性がある。
例えば、特定のプロセスを一つの CPU に括り付け
(すなわち、そのプロセスの affinity マスクを一つの CPU に設定し)、
他の全てのプロセスの affinity マスクからその CPU を除外することで、
確実にそのプロセスの実行速度を最大にすることができる。
また、あるプロセスの実行を一つの CPU に限定することで、
一つの CPU での実行を停止してから別の CPU で実行を再開するときに発生する
キャッシュ無効化 (cache invalidation) による性能面の劣化を防ぐこともできる。
CPU affinity マスクは「CPU の集合」を表す
cpu_set_t
構造体で表現され、
cpu_set_t
へのポインタ
mask
で指定される。
CPU 集合を操作するためのマクロが 4 種類提供されている。
CPU_ZERO
()は集合をクリアする。
CPU_SET
()と
CPU_CLR
()はそれぞれ指定された CPU の集合への追加/削除を行う。
CPU_ISSET
()はある CPU が集合に含まれているかの確認を行う。このマクロは
sched_getaffinity
()を呼び出した後で使用すると便利である。
システム上にある最初の CPU が
cpu
値 0 に、次の CPU は
cpu
値 1 に対応し、以後同様である。
定数
CPU_SETSIZE
(1024) は、CPU 集合に入る CPU 番号の最大値より 1 大きい値を示す。
sched_setaffinity
()は、プロセスID が
pid
のプロセスの CPU affinity マスクを
mask
で指定された値に設定する。
pid
が 0 の場合、呼び出し元プロセスが使われる。引き数
cpusetsize
には
mask
が指すデータの長さ (バイト単位) である。
通常は、この引き数には
sizeof(cpu_set_t)
を指定すればよい。
pid
で指定されたプロセスが
mask
で指定された CPU のいずれかで現在実行されていない場合、
そのプロセスは
mask
で指定された CPU のいずれかに移動される。
sched_getaffinity
()は、
プロセスID が
pid
のプロセスの affinity マスクを
mask
が指す
cpu_set_t
構造体に書き込む。
cpusetsize
引き数には
mask
の (バイト単位の) 大きさを指定する。
関数
sched_getaffinity
()は長さ
len
のポインタ
mask
にプロセス
pid
の affinity マスクを書き込む。
pid
が 0 の場合、呼び出し元のプロセスのマスクが返される。
返り値
成功した場合、 sched_setaffinity ()と sched_getaffinity ()は 0 を返す。 エラーの場合は -1 を返し、 errno を適切に設定する。
エラー
- EFAULT
- 指定されたメモリ番地が不正である。
- EINVAL
- affinity ビットマスク mask にシステム上に実際に存在するプロセッサに対応するビットがない。 またはマスク長 cpusetsize がカーネルで使われている affinity マスクより短い。
- EPERM
- 呼び出し元のプロセスに適切な特権がなかった。 sched_setaffinity ()を呼び出すプロセスは、実効ユーザ ID が pid で識別されるプロセスのユーザ ID または実効ユーザ ID と同じであるか、 CAP_SYS_NICE ケーパビリティ (capability) を持たなければならない。
- ESRCH
- プロセス ID pid のプロセスが見つからなかった。
準拠
これらのシステムコールは Linux 固有である。
注意
実際には affinity マスクはスレッド単位の属性で、スレッドグループの
各スレッド単位に独立して調整することができる。
gettid
(2) コールからの返り値をこのコールの
pid
引き数として渡すことができる。
fork
(2) 経由で生成された子プロセスは親プロセスの CPU affinity マスクを継承する。
affinity マスクは
execve
(2) の前後で保存される。
このマニュアルページでは CPU affinity コールの glibc インタフェースを
説明している。実際のシステムコール・インタフェースは少し違っており、
実際の実装では CPU 集合は簡単なビットマスクであるという実状を反映し、
mask
の型が
unsigned long *
となっている。
成功時には、生の
sched_getaffinity
()システムコール自身は
cpumask_t
データ型の (バイト単位の) 大きさを返す。
cpumask_t
はカーネル内部で CPU 集合のビットマスクを表現するのに
使われているデータ型である。
履歴
CPU affinity システムコールは Linux kernel 2.5.8 で導入された。 ライブラリ側のインタフェースは glibc 2.3 で導入された。 最初は、glibc のインタフェースには cpusetsize 引き数が入っていた。 glibc 2.3.2 では cpusetsize 引き数が削除されたが、glibc 2.3.4 で元に戻された。
関連項目
clone (2), getpriority (2), gettid (2), nice (2), sched_get_priority_max (2), sched_get_priority_min (2), sched_getscheduler (2), sched_setscheduler (2), setpriority (2), capabilities (7)
sched_setscheduler
(2) には Linux におけるスケジューリングの概略が記述されている。