Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];

Вниз

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

 
_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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.042 c
2-1166167971
ssss
2006-12-15 10:32
2007.01.21
Активное окно!


4-1157332834
Viacheslav
2006-09-04 05:20
2007.01.21
Контекстное меню проводника.


15-1167364204
Slider007
2006-12-29 06:50
2007.01.21
С днем рождения ! 29 декабря


15-1167778355
Footballer
2007-01-03 01:52
2007.01.21
Не могу найти сайт


15-1167745139
Parus
2007-01-02 16:38
2007.01.21
ASP





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский