#author("2019-10-02T08:56:31+09:00","default:honma","honma")
#author("2019-12-26T09:01:19+09:00","default:honma","honma")
* sched_getattr [#xc39e4ea]

スケジューリングポリシーやパラメータを取得する

* スケジューリングポリシー [#q13174e2]

+ リアルタイムポリシー
++ SCHED_FIFO~
このポリシーは static priority scheduling (静的優先順位スケジューリング) とも呼ばれる。~
各スレッドの静的優先順位 (1[最低] から 99[最高] の間で) を指定し、実行準備ができているもので最も優先順位が高いスレッドをスケジュールする。~
このスレッドは、ブロックまたは終了するか、実行準備ができた、より優先順位の高いスレッドに取って代わられるまで実行する。~
++ SCHED_RR~
SCHED_FIFO ポリシーのラウンドロビン版。~
SCHED_RR スレッドも静的優先順位 (1 から 99 の間で) が与えられる。~
優先順位が同じスレッドは、特定のクォンタム、または時間枠内でラウンドロビンでスケジュールされる。~
+ 通常のポリシー
++SCHED_OTHER/SCHED_NORMAL~
デフォルトのスケジューリングポリシー。~
静的優先順位は 0 で使用する。~
このポリシーは、Completely Fair Scheduler (CFS) を使って、このポリシーを使用するすべてのスレッドに対して公平なアクセス期間を提供する。~
スケジューリングは、静的優先度 0 のリストから、このリストの中だけで 決定される「動的な」優先度 (dynamic priority) に基いて決定される。 動的な優先度はnice 値に基づいて決定される。~
++SCHED_BATCH~
SCHED_BATCH は静的優先度 0 でのみ使用できる。~
このポリシーは(nice 値に基づく)動的な優先度にしたがってスレッドの スケジューリングが行われるという点で、SCHED_OTHER に似ている。~
スケジューラはスレッドを呼び起こす毎にそのスレッドにスケジューリング上の ペナルティを少し課し、その結果、このスレッドはスケジューリングの決定で 若干冷遇されるようになる。 ~
++SCHED_IDLE~
SCHED_IDLE は静的優先度 0 でのみ使用できる。~
このポリシーではプロセスの nice 値はスケジューリングに影響を与えない。~
非常に低い優先度でのジョブの実行を目的としたものである (非常に低い優先度とは、ポリシー SCHED_OTHER か SCHED_BATCH での nice 値 +19 よりさらに低い優先度である)。~

参考:[[スケジューリング API の概要:https://linuxjm.osdn.jp/html/LDP_man-pages/man7/sched.7.html]]

#highlight(c){{
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>

typedef unsigned long long u64;
typedef unsigned int u32;
typedef int s32;

struct sched_attr {
	u32 size;

	u32 sched_policy;
	u64 sched_flags;

	/* SCHED_NORMAL, SCHED_BATCH */
	s32 sched_nice;

	/* SCHED_FIFO, SCHED_RR */
	u32 sched_priority;

	/* SCHED_DEADLINE */
	u64 sched_runtime;
	u64 sched_deadline;
	u64 sched_period;
};

#define sched_getattr(pid, attr, size, flags) syscall(__NR_sched_getattr, pid, attr, size, flags)

void get_prio(void)
{
	int ret;
	int policy;
	struct sched_param param;
	struct sched_attr attr;

	policy = sched_getscheduler(0);
	printf("policy = %d\n", policy);

	ret = sched_getparam(0, &param);
	if (ret == 0) {
		printf("sched_priority = %d\n", param.sched_priority);
	}
	else {
		perror("sched_getparam");
	}

	/*
	 * sched_getattr() は glibcラッパー関数がないので自分で syscall() する
	 */
	ret = sched_getattr(0, &attr, sizeof(attr), 0);
	if (ret == 0) {
		printf("sched_policy = %d\n", attr.sched_policy);
		printf("sched_nice = %d\n", attr.sched_nice);
		printf("sched_priority = %d\n", attr.sched_priority);
	}
	else {
		perror("sched_getattr");
	}
}

int main(int argc, char **argv)
{
	get_prio();
	/* キー入力待ち */
	getchar();

	get_prio();
	/* キー入力待ち */
	getchar();

	return 0;
}
}}
#highlight(end)
[[ソースコード:https://www.chobits.com/pukiwiki/index.php?plugin=attach&pcmd=open&file=sched_get_prio.c&refer=sched_getattr]]

#ref(sched_get_prio.c)

実行結果

 $ ./sched_get_prio
 policy = 0
 sched_priority = 0
 sched_policy = 0
 sched_nice = 0
 sched_priority = 0
 
 ※ reniceで nice値を変えてみる
 
 policy = 0
 sched_priority = 0
 sched_policy = 0
 sched_nice = 1
 sched_priority = 0

別のターミナルから renice を実行

 $ cat /proc/`pidof sched_get_prio`/sched | grep -e policy -e prio
 sched_get_prio (93999, #threads: 1)
 policy                                       :                    0
 prio                                         :                  120
 $ cat /proc/`pidof sched_get_prio`/stat | awk -F' ' '{print $18,$19}'
 20 0
 
 $ sudo renice -n 1 -p `pidof sched_get_prio`
 [sudo] ****** のパスワード:
 93999 (process ID) old priority 0, new priority 1
 
 $ cat /proc/`pidof sched_get_prio`/sched | grep -e policy -e prio
 sched_get_prio (93999, #threads: 1)
 policy                                       :                    0
 prio                                         :                  121
 $ cat /proc/`pidof sched_get_prio`/stat | awk -F' ' '{print $18,$19}'
 21 1

#htmlinsert(amazon_pc.html);

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS