Приоритет планирования каждого потока в Linux с политикой планирования по умолчанию (SCHED_OTHER)C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Приоритет планирования каждого потока в Linux с политикой планирования по умолчанию (SCHED_OTHER)

Сообщение Anonymous »

Я пытаюсь реализовать кросс-платформенную оболочку для настройки приоритета текущего потока; в POSIX "правильная" вещь выглядит примерно так:

Код: Выделить всё

/// 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;
}
Это работает так, как я и ожидал в macOS (где потоки, похоже, имеют диапазон приоритетов [15, 47] со значением по умолчанию 31), но вообще не работает в Linux, поскольку с политикой по умолчанию (0 AKA SCHED_OTHER) диапазон разрешенных приоритетов равен [0, 0], т. е. регулировка приоритетов невозможна.
Вы можете переключить политику планирования на что-то вроде SCHED_FIFO или SCHED_RR и использовать их значения приоритета, но это совсем не то, что я хочу (из man 7 sched они всегда имеют приоритет над задачами SCHED_OTHER, а в в целом они подходят для очень специфических сценариев).
Вместо этого я обнаружил, что работает использование значения nice (через nice(2)/

Код: Выделить всё

setpriority(2)
), который, вопреки тому, что говорит POSIX, зависит от потока, а не от процесса (кажется, это довольно прямое следствие очень размытой границы между потоками и процессами в Linux, где все в конечном итоге является просто «задачой»). с различными возможными общими вещами с другими задачами). В итоге у меня получилось:

Код: Выделить всё

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
}
что кажется достаточно хорошим, но потом я заметил в man 2 setpriority:

Согласно POSIX значение nice — это настройка для каждого процесса. Однако в текущей реализации потоков POSIX в Linux/NPTL значение nice является атрибутом каждого потока: разные потоки в одном процессе могут иметь разные значения nice. Портативным приложениям не следует полагаться на поведение Linux, которое в будущем может быть приведено в соответствие со стандартами.

Итак, если я хочу быть ориентированным на будущее, но при этом иметь возможность регулировать приоритет потоков с помощью политики планирования по умолчанию SCHED_OTHER, что мне делать?
A возможность, которая приходит на ум, - это работать в резервном режиме: запустите sched_get_priority_min/

Код: Выделить всё

sched_get_priority_max
танцуйте, и если окажется, что это [0,0] И мы находимся в Linux, предположим, что мы находимся в ситуации, когда значение nice дается для каждого потока (идея состоит в том, что если значение nice значение когда-либо создается для каждого потока, элементы pthreads должны начать работать должным образом, с доступным диапазоном значений).

Код: Выделить всё

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
}
Есть ли какая-то лучшая возможность/API, которую я пропустил?

Подробнее здесь: https://stackoverflow.com/questions/784 ... eduling-po
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»