#author("2020-02-07T13:33:56+09:00","default:honma","honma")
#author("2020-02-07T13:37:49+09:00","default:honma","honma")
* スレッドのプライオリティ(setpriority版) [#vfd46bf2]

前回の[[nice版>スレッドのプライオリティ(nice版)]]より、使い勝手の良いsetpriorityを使用してみた。~
glibc 2.2.4 以降では、 nice() は getpriority(2) を呼び出すライブラリ関数として実装されている。情報元は[[こちら:http://linuxjm.osdn.jp/html/LDP_man-pages/man2/nice.2.html]]~
前回の[[nice版>スレッドのプライオリティ(nice版)]]より、使い勝手の良いsetpriority()を使用してみた。~
glibc 2.2.4 以降では、 nice() は getpriority() を呼び出すライブラリ関数として実装されている。情報元は[[こちら:http://linuxjm.osdn.jp/html/LDP_man-pages/man2/nice.2.html]]~
懸念点があるとすれば、本来はプロセス単位で制御する点で、今後の互換性や移植性に難あり。

参考:[[Man page of GETPRIORITY:https://linuxjm.osdn.jp/html/LDP_man-pages/man2/setpriority.2.html]]

#highlight(c){{
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>

typedef struct {
	pthread_t thread;
} thread_param_t;

/* スレッドID を取得する */
pid_t gettid(void)
{
	/*
	 *  glibc のラッパー関数が存在しないので間接システムコールを用いる
	 */
	pid_t tid;

	tid = syscall(SYS_gettid);

	return tid;
}

/* プライオリティ表示 */
void disp_prio(int pid, int tid)
{
	char head_msg[] = "head -n1 /proc/%d/sched";
	char sched_msg[] = "cat /proc/%d/sched | grep -A 1 policy";
	char msg[80] = {0};

	/* メインプロセスのプライオリティ */
	sprintf(msg, head_msg, pid);
	system(msg);
	sprintf(msg, sched_msg, pid);
	system(msg);

	/* スレッドのプライオリティ */
	sprintf(msg, head_msg, tid);
	system(msg);
	sprintf(msg, sched_msg, tid);
	system(msg);
}

/* スレッド */
void *thread_test(void *args)
{
	int ret;
	int pid, tid;
	int policy;
	int prio[3] = {19, -1, 0};
	struct sched_param schedParam;
	thread_param_t *thread_param = args;
	int i;

	pid = (int)getpid();
	tid = (int)gettid();
	printf("thread_test: pid = %d tid= %d\n", pid, tid);
	disp_prio(pid, tid);

	/* スレッドのスケージューリングパラメータを取得する */
	ret = pthread_getschedparam(thread_param->thread, &policy, &schedParam);
	if (ret != 0) {
		fprintf(stderr, "pthread_getschedparam = %d\n", ret);
	}
	printf("policy = %d, sched_priority = %d\n", policy, schedParam.sched_priority);

	for (i=0; i<3; i++) {
		printf("change nice = %d\n", prio[i]);

		/* スレッドプライオリティの変更 */
		errno = 0;
		ret = setpriority(PRIO_PROCESS, 0, prio[i]);
		if (errno != 0) {
			perror("setpriority");
		}
		disp_prio(pid, tid);

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

	/* スレッドの終了 */
	pthread_exit(NULL);
}

/* メイン */
int main(void)
{
	int ret;
	thread_param_t thread_param;

	printf("my pid = %d\n", getpid());

	/* 新しいスレッドを作成する */
	ret = pthread_create(&thread_param.thread, NULL, thread_test, &thread_param);
	if (ret != 0) {
		fprintf(stderr, "pthread_create = %d\n", ret);
	}

	/* 終了したスレッドを join する */
	ret = pthread_join(thread_param.thread, NULL);
	if (ret != 0) {
		fprintf(stderr, "pthread_join = %d\n", ret);
	}

	return 0;
}
}}
#highlight(end)

#ref(thread_setpriority.tgz)

実行結果

 $ ./thread_setpriority
 my pid = 74433
 thread_test: pid = 74433 tid= 74434
 thread_setprior (74433, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74434, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 policy = 0, sched_priority = 0
 change nice = 19
 thread_setprior (74433, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74434, #threads: 2)
 policy                                       :                    0
 prio                                         :                  139
 
 change nice = -1
 setpriority: Permission denied
 thread_setprior (74433, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74434, #threads: 2)
 policy                                       :                    0
 prio                                         :                  139
 
 change nice = 0
 setpriority: Permission denied
 thread_setprior (74433, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74434, #threads: 2)
 policy                                       :                    0
 prio                                         :                  139
 
前回の[[nice版>スレッドのプライオリティ(nice版)]]同様にプライオリティを上げたいときはroot特権が必要。(Operation not permitted になる)~
nice()と異なりデフォルトに対する相対値なので、プライオリティに0を指定してもエラーになるケースが出る。~

 $ sudo ./thread_setpriority
 my pid = 74476
 thread_test: pid = 74476 tid= 74477
 thread_setprior (74476, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74477, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 policy = 0, sched_priority = 0
 change nice = 19
 thread_setprior (74476, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74477, #threads: 2)
 policy                                       :                    0
 prio                                         :                  139
 
 change nice = -1
 thread_setprior (74476, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74477, #threads: 2)
 policy                                       :                    0
 prio                                         :                  119
 
 change nice = 0
 thread_setprior (74476, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 thread_setprior (74477, #threads: 2)
 policy                                       :                    0
 prio                                         :                  120
 
[[nice版>スレッドのプライオリティ(nice版)]]と異なり、デフォルトに対する相対値で指定できるだけ使い勝手は良い。

#htmlinsert(amazon_pc.html);

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