Форум: "Прочее";
Текущий архив: 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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
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, ¶m);
if (ret == 0) {
printf("Set SCHED 1 success\n");
} else {
printf("Failure 1\n");
}
ret = pthread_getschedparam(thread1, &policy, ¶m);
if (ret == 0) {
printf("Thread1 priority is %d\n", param.sched_priority);
}
param.sched_priority = 1;
policy = SCHED_RR;
ret = pthread_setschedparam(thread2, policy, ¶m);
if (ret == 0) {
printf("Set SCHED 2 success\n");
} else {
printf("Failure 2\n");
}
ret = pthread_getschedparam(thread2, &policy, ¶m);
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, ¶m);
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, ¶m);
policy = SCHED_FIFO;
param.sched_priority = 30;
ret = sched_setscheduler(getpid(), policy, ¶m);
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