Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.01.21;
Скачать: CL | DM;

Вниз

Приоритет потоков   Найти похожие ветки 

 
_uw_   (2007-01-02 18:25) [0]

Есть шанс, что именно здесь меня вразумят раньше, чем в других местах :)
Я работаю под Linux"ом, и мне надо поменять приоритет потока. Я это пытаюсь сделать следующим образом:

#include <pthread.h>
#include <stdio.h>

static void *my_thread(void *arg)
{
sleep(1);
}

int main(void)
{
pthread_t thread;
int priority;
int policy;
struct sched_param param;
int res;

pthread_create(&thread, NULL, my_thread, NULL);

res = pthread_getschedparam(thread, &policy, &param);
priority = param.sched_priority;
printf("res = %d  policy = %d  priority = %d\n", res, policy, priority);

param.sched_priority = 2;
policy = SCHED_OTHER;
res = pthread_setschedparam(thread, policy, &param);
printf("res = %d\n", res);

pthread_join(thread, 0);

return 0;
}


В результате получаю:

res = 0 policy = 0 priority = 0
res = 22

Код 22 означает что-то типа "недопустимый параметр". Что делаю не так?


 
umbra ©   (2007-01-02 18:55) [1]

стоит проверять возвращаемые функциями значения. На момент проверки параметров потока он еще существует?


 
Zeqfreed ©   (2007-01-02 19:12) [2]

При использовании SCHED_OTHER нельзя менять приоритет потока. (http://linux.about.com/library/cmd/blcmdl2_sched_setscheduler.htm)


 
_uw_   (2007-01-02 19:35) [3]

Спасибо за ссылку.


 
_uw_   (2007-01-02 22:10) [4]

Не получается :(

Пишу:

res = pthread_attr_init(&attr);
attr.__schedpolicy = SCHED_FIFO;  // SCHED_FIFO = 1
attr.__schedparam.sched_priority = 5;

res = pthread_create(&thread, &attr, my_thread, &thread);
res = pthread_getschedparam(thread, &policy, &param);
printf("rs = %d  policy = %d  priority = %d\n", res, policy,  param.sched_priority);

Получаю результат:

res = 0 policy = 0 priority = 0


 
Zeqfreed ©   (2007-01-02 22:38) [5]

Зачем ты только запостил это сюда? :)
Я уже 5 раз перезагружался, потому что мои изощрения с потоками вешают систему намертво. Хотя приоритет у меня получилось изменить ))

#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int a[2] = {0, 0};

static void *my_thread(void *arg)
{
while (1) {
 pthread_mutex_lock(&mutex);
 a[(int)arg] = a[(int)arg] + 1;
 pthread_mutex_unlock(&mutex);
 pthread_yield();
 sleep(2); //Если это убрать, то программа вешает систему ;)
}
}

int main(void)
{
pthread_t thread1, thread2;
int priority;
int policy, newprio;
struct sched_param param;
int ret;

printf("%d %d %d %d\n", EPERM, EINVAL, ENOTSUP, ESRCH);
printf("%d %d %d\n", SCHED_OTHER, SCHED_RR, SCHED_FIFO);

policy = SCHED_RR;
param.sched_priority = 2;
ret = sched_setscheduler(getpid(), policy, &param);
if(ret == 0) {
 printf("Set SCHED process success\n");
} else if (ret == EPERM)
{
 printf("No Permission\n");
}

nice(15);

pthread_create(&thread1, NULL, &my_thread, (void *)(0));
pthread_create(&thread2, NULL, &my_thread, (void *)(1));

       param.sched_priority = 2;
       policy = SCHED_RR;
       ret = pthread_setschedparam(thread1, policy, &param);
 if (ret == 0) {
 printf("Set SCHED 1 success\n");
} else {
 printf("Failure 1\n");
}
ret = pthread_getschedparam(thread1, &policy, &param);
if (ret == 0) {
 printf("Thread1 priority is %d\n", param.sched_priority);
}

       param.sched_priority = 1;
       policy = SCHED_RR;
       ret = pthread_setschedparam(thread2, policy, &param);
 if (ret == 0) {
 printf("Set SCHED 2 success\n");
} else {
 printf("Failure 2\n");
}
ret = pthread_getschedparam(thread2, &policy, &param);
if (ret == 0) {
 printf("Thread2 priority is %d\n", param.sched_priority);
}

while (1) {
 pthread_mutex_lock(&mutex);
 printf("%d\t%d\n", a[0], a[1]);
 pthread_mutex_unlock(&mutex);
 usleep(5000);
}

return 0;
}


Я вот пока до чего дошёл. Пытаюсь визуально увидеть, что один поток имеет больший приоритет, но пока только получаю необходимость перезагружаться каждый раз когда я запускаю это :)


 
_uw_   (2007-01-02 23:47) [6]

 sleep(2); //Если это убрать, то программа вешает систему ;)

У меня, когда комментирую эту строку, ничего не вешается. Но и с приоритетами беда.


 
Zeqfreed ©   (2007-01-03 00:26) [7]

Надо не только эту :)
Я, кажется, начал понимать: http://tree.celinuxforum.org/pipermail/celinux-dev/2006-June/001238.html

Т.е. когда ставишь политику SCHED_RR или SCHED_FIFO, то поток с высшим приоритетом будет выполнятся пока его принудительно не прервать (например, выполнив pthread_yield). А вот как тогда обеспечить различные приоритеты для потоков с политикой SCHED_OTHER если там нельзя менять приоритет, мне не понятно :(


 
Zeqfreed ©   (2007-01-03 01:00) [8]

В общем, насколько я понял, то приложение должно само контролировать как оно хочет распределять время между потоками. Для точного распределения времени существуют политики с динамическим приоритетом (SCHED_RR/SCHED_FIFO), для неточного нужно использовать SCHED_OTHER без возможности задавать динамический приоритет разным потокам.

В итоге вот что у меня получилось:

#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int thread_vars[2] = {0, 0};

static safe_inc(int *x)
{
pthread_mutex_lock(&mutex);
*x += 1;
pthread_mutex_unlock(&mutex);
}

static void *thread_proc(void *arg)
{
while (1)
{
 safe_inc(&thread_vars[(int)arg]);
 if ((int)arg == 0) usleep(1);
}
}

int main(void)
{
pthread_t thread1, thread2;

pthread_create(&thread1, NULL, thread_proc, (void *)(0));
pthread_create(&thread2, NULL, thread_proc, (void *)(1));

int x, y;
while (1)
{
 pthread_mutex_lock(&mutex);
 x = thread_vars[0];
 y = thread_vars[1];
 pthread_mutex_unlock(&mutex);
 
 printf("%d\t%d\n", x, y);
 usleep(100);
}

return 0;
}


Т.е. создаются 2 потока и один из них искуственно замедляется вызовом usleep. Второй автоматически получает "больший приоритет".


 
_uw_   (2007-01-03 01:16) [9]

Похоже, политика не меняется вообще и всегда SCHED_OTHER. Потоки получают квант времени, зависящий от параметра функции nice(1), - чем больше его значение, тем меньше квант. Это, конечно, не реальное время, но и так жить можно.

Спасибо за помощь, особенно за nice.


 
Zeqfreed ©   (2007-01-03 01:29) [10]

У меня политика меняется, но с риалтаймовой политикой видимо шутки плохи и у меня не получилось её усмирить. А nice меняет приоритет всего процесса, вот там можно и динамический приоритет задавать относительно других процессов и все остальное, там все работает. От него, разумеется, зависят и выделяемые кванты времени.

Надеюсь хоть чем-то помог :) Для себя лично много нового узнал :)


 
_uw_   (2007-01-03 10:27) [11]

Поиграл еще немного, но уже на контрголлере, для которого и пишу программу. Вот что получается:

1. В режиме пользователя работает только SCHED_OTHER. Именно это я и наблюдал вчера в Red Hat.
2. В режиме супервизора работают и остальные политики. В этом режиме у меня запускается процесс на контроллере.
3. Чем больше параметр priority, тем выше приоритет. Я почему-то думал наоборот.

Окончательный вариант теста для контроллера работает в точности так, как и ожидается. В нем я убрал задержку в низкоприоритетном потоке, потому что она только затеняет происходящее. Кроме того, не нужны и мьютексы, потому что операции с int атомарные - на то оно и int!

Вот текст (о прерывании процесса посредством Ctrl-C я не заботился, потому что контроллер у меня перезагружается достаточно быстро):

#include <pthread.h>
#include <sched.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

static int a[2] = {0, 0};

static void *my_thread(void *arg)
{
int numb = (int)arg;
int policy;
struct sched_param param;
int count = 0;
int res;

policy = SCHED_FIFO;
if (numb == 0)
 param.sched_priority = 5;
else
 param.sched_priority = 10;

res = sched_setscheduler(getpid(), policy, &param);

while (1) {
 a[numb]++;
 count++;
 if (numb == 1) {
  if (count == 1000) {
   count = 0;
   usleep(1000);
  }
 }
}
}

int main(void)
{
pthread_t thread1, thread2;
int priority;
int policy, newprio;
struct sched_param param;
int ret;

ret = pthread_getschedparam(thread1, &policy, &param);

policy = SCHED_FIFO;
param.sched_priority = 30;
ret = sched_setscheduler(getpid(), policy, &param);

pthread_create(&thread1, NULL, &my_thread, (void *)0);
pthread_create(&thread2, NULL, &my_thread, (void *)1);

while (1) {
 printf("%d\t%d\n", a[0], a[1]);
 usleep(1000);
}

return 0;
}


 
_uw_   (2007-01-03 10:38) [12]

_uw_   (03.01.07 10:27) [11]
Поиграл еще немного, но уже на контрголлере


Вот ведь! Из какого-то поколения вылезло :)


 
Zeqfreed ©   (2007-01-03 10:39) [13]


> _uw_   (03.01.07 10:27) [11]

У меня этот код вешает систему :) Ну т.е. процесс отъедает все процессорное время, на консоль даже ничего не успевает вывести, тут же все замирает, и "спасает" только Alt+SysRq+b. Не могу понять почему и как сделать по-человечески :(


 
Zeqfreed ©   (2007-01-03 10:43) [14]

Или риалтаймовые политики рассчитаны на то, что кроме риалтаймовых процессов никакие другие не должны выполняться? Тогда видимо для обычных задач нужно использовать искуственную паузу как я в [8] предположил?


 
umbra ©   (2007-01-03 10:43) [15]


> У меня этот код вешает систему

у вас ядра разные, наверное. Можно попробовать param.sched_priority уменьшить.


 
umbra ©   (2007-01-03 10:49) [16]

как написано в man sched_setparam, максимальное значение приоритета можно получить с помощью sched_get_priority_max


 
Zeqfreed ©   (2007-01-03 10:51) [17]

Да читал я это все :) И пробовал все. Виснет оно при любом значении. Может ядро глючное попалось конечно, но что-то я в этом глубоко сомневаюсь. Щас ради эксперимента попробую на другом ядре.


 
Zeqfreed ©   (2007-01-03 11:01) [18]

Как и следовало ожидать, вывелось 0 0 и зависло. :(


 
umbra ©   (2007-01-03 11:34) [19]

так а чего ж Вы хотите. Вы создаете 2 потока с высоким приоритетом, выполнение которых никак не прерывается и хотите чего-то печатать в потоке с низким приоритетом


 
Zeqfreed ©   (2007-01-03 11:52) [20]

Прерывается usleep"ом. Но этого мало, т.к., насколько я понял, любой процесс с политикой реального времени будет выполнятся раньше всех остальных. Поэтому использовать эти политики на настольных системах не представляется возможным.

Там вообще 3 потока, у главного приоритет 30. Понятное дело, что они не оставляют системе шансов заиметь хотя бы кусочек процессорного времени. Я одного не понимаю, почему у _uw_ работает, по его словам :)


 
_uw_   (2007-01-03 14:25) [21]

Zeqfreed ©   (03.01.07 11:52) [20]
Там вообще 3 потока, у главного приоритет 30. Понятное дело, что они не оставляют системе шансов заиметь хотя бы кусочек процессорного времени. Я одного не понимаю, почему у _uw_ работает, по его словам :)

У меня всё в режиме супервизора, поэтому, видимо, и работает.



Страницы: 1 вся ветка

Текущий архив: 2007.01.21;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.063 c
15-1167240881
kroner
2006-12-27 20:34
2007.01.21
TIdHTTPServer + SSI-обработка


15-1167517970
ANTPro
2006-12-31 01:32
2007.01.21
rsdn.ru


1-1164733553
Piter_Sid
2006-11-28 20:05
2007.01.21
StringGrid


2-1167949022
alll
2007-01-05 01:17
2007.01.21
Работа с компонентами Delphi


8-1148549281
Belorus
2006-05-25 13:28
2007.01.21
Чтение текста голосом.