Код: Выделить всё
/// set the priority adjustment for the current thread
/// @param pri priority between -2 and 2; 0 is the "normal" priority
/// @return true if successful
bool czu::set_thread_priority(int pri) {
struct sched_param sp;
int policy;
pthread_t self = pthread_self();
if (pthread_getschedparam(self, &policy, &sp) != 0) return false;
int pmin = sched_get_priority_min(policy);
int pmax = sched_get_priority_max(policy);
if (pmin == -1 || pmax == -1) return false;
sp.sched_priority = pmin + (pmax-pmin) * (pri + 2) / 4;
return pthread_setschedparam(self, policy, &sp) == 0;
}
Вы можете переключить политику планирования на что-то вроде SCHED_FIFO или SCHED_RR и использовать их значения приоритета, но это совсем не то, что я хочу (из man 7 sched они всегда имеют приоритет над задачами SCHED_OTHER, а в в целом они подходят для очень специфических сценариев).
Вместо этого я обнаружил, что работает использование значения nice (через nice(2)/
Код: Выделить всё
setpriority(2)
Код: Выделить всё
bool czu::set_thread_priority(int pri) {
if (pri < -2) pri = -2;
if (pri > 2) pri = 2;
#ifdef _WIN32
// %pri was conveniently chosen so that it matches SetThreadPriority
return SetThreadPriority(GetCurrentThread(), pri);
#elif __linux__
// On Linux the pthread_setschedparam stuff works only with particular
// scheduling policies, specifically it does not work with the default one;
// instead, nice(2)/setpriority(2) works, and affects only the current
// thread instead of doing what POSIX would say (whole process).
// Here the allowed range is [20, -19] (20 = minimum priority); we can
// ignore clamping -20 as setpriority is already guaranteed to do it.
return setpriority(PRIO_PROCESS, 0, pri*-10) == 0;
#else
struct sched_param sp;
int policy;
pthread_t self = pthread_self();
if (pthread_getschedparam(self, &policy, &sp) != 0) return false;
int pmin = sched_get_priority_min(policy);
int pmax = sched_get_priority_max(policy);
if (pmin == -1 || pmax == -1) return false;
sp.sched_priority = pmin + (pmax-pmin) * (pri + 2) / 4;
return pthread_setschedparam(self, policy, &sp)) == 0;
#endif
}
Согласно POSIX значение nice — это настройка для каждого процесса. Однако в текущей реализации потоков POSIX в Linux/NPTL значение nice является атрибутом каждого потока: разные потоки в одном процессе могут иметь разные значения nice. Портативным приложениям не следует полагаться на поведение Linux, которое в будущем может быть приведено в соответствие со стандартами.
Итак, если я хочу быть ориентированным на будущее, но при этом иметь возможность регулировать приоритет потоков с помощью политики планирования по умолчанию SCHED_OTHER, что мне делать?
A возможность, которая приходит на ум, - это работать в резервном режиме: запустите sched_get_priority_min/
Код: Выделить всё
sched_get_priority_max
Код: Выделить всё
bool czu::set_thread_priority(int pri) {
if (pri < -2) pri = -2;
if (pri > 2) pri = 2;
#ifdef _WIN32
// %pri was conveniently chosen so that it matches SetThreadPriority
return SetThreadPriority(GetCurrentThread(), pri);
#else
struct sched_param sp;
int policy;
pthread_t self = pthread_self();
// on POSIX the admissible priorities range isn't fixed, and depends from
// the scheduler policy for the thread; let's figure all this out
if (pthread_getschedparam(self, &policy, &sp) != 0) return false;
int pmin = sched_get_priority_min(policy);
int pmax = sched_get_priority_max(policy);
if (pmin == -1 || pmax == -1) return false;
#ifdef __linux__
if (pmax - pmin == 0) {
// On Linux the pthread_setschedparam stuff works only with particular
// scheduling policies, specifically it does not work with the default
// one; instead, nice(2)/setpriority(2) works, and affects only the
// current thread instead of doing what POSIX would say (whole process).
// Here the allowed range is [20, -19] (20 = minimum priority); we can
// ignore clamping -20 as setpriority is already guaranteed to do it.
return setpriority(PRIO_PROCESS, 0, pri*-10) == 0;
}
#endif
// plain linear interpolation
sp.sched_priority = pmin + (pmax-pmin) * (pri + 2) / 4;
return pthread_setschedparam(self, policy, &sp) == 0;
#endif
}
Подробнее здесь: https://stackoverflow.com/questions/784 ... eduling-po