#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);