Мне нужно управлять пулом потоков с разными приоритетами, поэтому я написал следующую процедуру запуска потока:
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
assert(pthread_attr_init(&attr) == 0);
assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0);
assert(pthread_attr_setschedparam(&attr, ¶m) == 0);
err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd);
pthread_attr_destroy(&attr);
return err;
}
В принципе непривилегированный пользователь не должен иметь права выполнять этот код: вызов pthread_create () должен возвращать EPERM из-за последствий для безопасности запуска потока с высоким приоритетом.
Неожиданно он работает для обычного пользователя, но он вообще не уважает данный приоритет.
Я попытался изменить код, удалив pthread_attr_t
и установив атрибут планирования после создания потока:
static
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio)
{
pthread_attr_t attr;
int err;
struct sched_param param = {
.sched_priority = prio
};
err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine,
(void *)thrd);
if (err != 0) return err;
err = pthread_setschedparam(thrd->handler, SCHED_FIFO, ¶m);
if (err != 0) return err;
return err;
}
Кстати, этим подходом гораздо сложнее управлять, так как в случае ошибки мне нужно уничтожить только что созданный поток. По крайней мере, кажется, что он работает должным образом в отношении требований к разрешениям (это может выполнить только root), но приоритеты все еще не соблюдаются.
Я что-то не так делаю?
EDIT
Я только что добавил следующий фрагмент кода, который выполняется каждым потоком:
static
void getinfo ()
{
struct sched_param param;
int policy;
sched_getparam(0, ¶m);
DEBUG_FMT("Priority of this process: %d", param.sched_priority);
pthread_getschedparam(pthread_self(), &policy, ¶m);
DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d",
param.sched_priority, policy, SCHED_FIFO);
}
При первом методе (а именно pthread_attr_t
подход) выясняется, что pthread_attr_setschedpolicy совершенно не эффективна, поскольку приоритет равен 0, а политика не SCHED_FIFO.
При втором методе (а именно pthread_setschedparam
подход) функция печатает ожидаемые данные, но выполнение продолжает вести себя неправильно.