#author("2020-02-07T12:06:01+09:00","default:honma","honma") #author("2020-02-07T13:35:56+09:00;2020-02-07T12:06:02+09:00","default:honma","honma") * スレッドのプライオリティ [#l3287780] スレッドのプライオリティを行うサンプルコード。~ ~ ポイントは - pthread_attr_setinheritsched を使わないと反映されない - SCHED_OTHER 以外はroot特権が必要。しかも、特権なしだと下げるだけ - pthread_attr_setschedparam の前に pthread_attr_setschedpolicy を実行 参考:[[Man page of SCHED:https://linuxjm.osdn.jp/html/LDP_man-pages/man7/sched.7.html]]~ 参考:[[Man page of PTHREAD_ATTR_INIT:https://linuxjm.osdn.jp/html/glibc-linuxthreads/man3/pthread_attr_setschedparam.3.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> typedef struct { pthread_t thread; } thread_param_t; /* スレッドID を取得する */ pid_t gettid(void) { /* * glibc のラッパー関数が存在しないので間接システムコールを用いる */ pid_t tid; tid = syscall(SYS_gettid); return tid; } /* スレッドプライオリティの変更 */ void set_thread_prio(thread_param_t *thread_param, int prio) { int ret; int policy; struct sched_param schedParam; /* スレッドのスケージューリングパラメータを取得する */ ret = pthread_getschedparam(thread_param->thread, &policy, &schedParam); if (ret != 0) { fprintf(stderr, "pthread_getschedparam = %d\n", ret); } /* スレッドのスケージューリングパラメータを設定する */ schedParam.sched_priority = prio; ret = pthread_setschedparam(thread_param->thread, policy, &schedParam); if (ret != 0) { fprintf(stderr, "pthread_setschedparam = %d\n", ret); } } /* プライオリティ表示 */ 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, prio = 20; struct sched_param schedParam; thread_param_t *thread_param = args; 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); printf("change priority = %d\n", prio); /* スレッドプライオリティの変更 */ set_thread_prio(thread_param, prio); disp_prio(pid, tid); /* キー入力待ち */ getchar(); /* スレッドの終了 */ pthread_exit(NULL); } /* メイン */ int main(void) { int ret; pthread_attr_t attr; struct sched_param schedParam; thread_param_t thread_param; printf("my pid = %d\n", getpid()); /* スレッド属性オブジェクトの初期化と破棄を行う */ ret = pthread_attr_init(&attr); if (ret != 0) { fprintf(stderr, "pthread_attr_init = %d\n", ret); } /* inherit-scheduler 属性の設定/取得を行う */ ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); if (ret != 0) { fprintf(stderr, "pthread_attr_setinheritsched = %d\n", ret); } /* スケジューリングポリシー属性の設定を行う */ ret = pthread_attr_setschedpolicy(&attr, SCHED_RR); if (ret != 0) { fprintf(stderr, "pthread_attr_setschedpolicy = %d\n", ret); } /* スケジューリングパラメーター属性の設定を行う */ schedParam.sched_priority = 10; ret = pthread_attr_setschedparam(&attr, &schedParam); if (ret != 0) { fprintf(stderr, "pthread_attr_setschedparam = %d\n", ret); } /* 新しいスレッドを作成する */ ret = pthread_create(&thread_param.thread, &attr, 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_prio.tgz) 実行結果 $ sudo ./thread_prio my pid = 72692 thread_test: pid = 72692 tid= 72693 thread_prio (72692, #threads: 2) policy : 0 prio : 120 thread_prio (72693, #threads: 2) policy : 2 prio : 89 policy = 2, sched_priority = 10 change priority = 20 thread_prio (72692, #threads: 2) policy : 0 prio : 120 thread_prio (72693, #threads: 2) policy : 2 prio : 79 #htmlinsert(amazon_pc.html);