Russian Qt Forum
Ноябрь 23, 2024, 23:06 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: priority основного потока (GUI)  (Прочитано 8231 раз)
kkk777kkk
Гость
« : Февраль 23, 2010, 13:37 »

Задумал выставлять программе высокий приоритет и было бы удобно делать это и для основного потока и при создании остальных приоритет будет сохраняться. Почему-то не нашел как делать это красиво для основного потока (есть вторичных все просто), но нашел хитрый метод вот по ссылке http://lists.trolltech.com/qt-interest/2006-05/thread00831-0.html

Но почему же этого функционала нету в стандартной поставке? Может это как-то не красиво с точки зрения стиля или чем-то чревато? И вообще на сколько вам нравится предложенное там решение?
Записан
ритт
Гость
« Ответ #1 : Февраль 23, 2010, 14:18 »

вариант, предложенный AndreaG, вполне работоспособен.
но также следует иметь в виду, что на различных платформах существуют определённые ограничения на установку приоритетов потокам.
Записан
kkk777kkk
Гость
« Ответ #2 : Февраль 23, 2010, 14:40 »

спасибо, буду иметь в виду, если соберемся на линух идти
Записан
kkk777kkk
Гость
« Ответ #3 : Февраль 23, 2010, 15:58 »

я вот посмотрел еще раз и в том топике пользователь жаловался, что нашел винапишное решение, а ему надо и на макось и на юникс, а в ассистанте написано "The effect of the priority parameter is dependent on the operating system's scheduling policy. In particular, the priority will be ignored on systems that do not support thread priorities (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler for more details).", то как же ему это помогло...

Записан
SABROG
Гость
« Ответ #4 : Февраль 23, 2010, 16:28 »

Еще пара вариантов.

Код
C++ (Qt)
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
 
class Object : public QObject
{
   Q_OBJECT;
public:
   Object(QObject *parent = 0) : QObject(parent) {}
   Q_INVOKABLE void setThreadPriority(int priority)
   {
       qApp->thread()->setPriority(static_cast<QThread::Priority>(priority));
   }
};
 
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   Object object;
   QMetaObject::invokeMethod(&object, "setThreadPriority", Qt::QueuedConnection, Q_ARG(int, static_cast<int>(QThread::HighestPriority)));
   return a.exec();
}
 
#include "main.moc"
 

Код
C++ (Qt)
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <QtCore/QMetaType>
 
Q_DECLARE_METATYPE(QThread::Priority)
class CoreApplication : public QCoreApplication
{
       Q_OBJECT;
public:
       CoreApplication(int& argc, char* argv[], QThread::Priority priority = QThread::InheritPriority)
           : QCoreApplication(argc, argv)
       {
           qRegisterMetaType<QThread::Priority>();
           connect(this, SIGNAL(priorityChanged(QThread::Priority)),
                           SLOT(changePriority(QThread::Priority)),
                           Qt::QueuedConnection);
           if (priority != QThread::InheritPriority)
               setPriority(priority);
       }
 
       inline void setPriority(QThread::Priority priority) {emit priorityChanged(priority);}
       inline QThread::Priority priority() const {return thread()->priority();}
protected slots:
       void changePriority(QThread::Priority priority)
       {
           thread()->setPriority(priority);
       }
signals:
       void priorityChanged(QThread::Priority priority);
};
 
int main(int argc, char *argv[])
{
   CoreApplication a(argc, argv, QThread::HighestPriority);
   return a.exec();
}
 
#include "main.moc"
 

Для Windows стоит разделять понятия "класс приоритета приложения" и "приоритет потока". Все приложения изначально получают класс приоритета NORMAL_PRIORITY_CLASS и приоритет потока THREAD_PRIORITY_NORMAL. Предположим, что мы вызываем метод QThread::setPriority(QThread::TimeCriticalPriority), чтобы выделить самый высокий приоритет. К нашему удивлению в том же TaskManager'e приоритет будет стоять "Средний". Но в Windows количество возможных приоритетов аж 31 штука. Самый высокий достигается комбинацией установки класса REALTIME_PRIORITY_CLASS и приоритета THREAD_PRIORITY_TIME_CRITICAL. В Qt нет возможности установки класса приоритета, поэтому решением может быть вызов WINAPI ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);, установка класса через TaskManager и установка класса приоритета в момент запуска приложения:

//cmd
Код:
start /REALTIME myprogram.exe

//terminal
Код:
nice -n 20 myprogram

Цитировать
я вот посмотрел еще раз и в том топике пользователь жаловался, что нашел винапишное решение, а ему надо и на макось и на юникс, а в ассистанте написано "The effect of the priority parameter is dependent on the operating system's scheduling policy. In particular, the priority will be ignored on systems that do not support thread priorities (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler for more details).", то как же ему это помогло...
Судя по коду ниже, работа приоритетов возможна под linux, но не гарантируется.

Код
C++ (Qt)
void QThread::setPriority(Priority priority)
{
   Q_D(QThread);
   QMutexLocker locker(&d->mutex);
   if (!d->running) {
       qWarning("QThread::setPriority: Cannot set priority, thread is not running");
       return;
   }
 
   d->priority = priority;
 
   // copied from start() with a few modifications:
 
#if defined(Q_OS_DARWIN) || !defined(Q_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0)
   int sched_policy;
   sched_param param;
 
   if (pthread_getschedparam(d->thread_id, &sched_policy, &param) != 0) {
       // failed to get the scheduling policy, don't bother setting
       // the priority
       qWarning("QThread::setPriority: Cannot get scheduler parameters");
       return;
   }
 
   int prio_min = sched_get_priority_min(sched_policy);
   int prio_max = sched_get_priority_max(sched_policy);
   if (prio_min == -1 || prio_max == -1) {
       // failed to get the scheduling parameters, don't
       // bother setting the priority
       qWarning("QThread::setPriority: Cannot determine scheduler priority range");
       return;
   }
 
   int prio;
   switch (priority) {
   case InheritPriority:
       qWarning("QThread::setPriority: Argument cannot be InheritPriority");
       return;
 
   case IdlePriority:
       prio = prio_min;
       break;
 
   case TimeCriticalPriority:
       prio = prio_max;
       break;
 
   default:
       // crudely scale our priority enum values to the prio_min/prio_max
       prio = (priority * (prio_max - prio_min) / TimeCriticalPriority) + prio_min;
       prio = qMax(prio_min, qMin(prio_max, prio));
       break;
   }
 
   param.sched_priority = prio;
   pthread_setschedparam(d->thread_id, sched_policy, &param);
#endif
}
 
---
У меня установка приоритета работает и до запуска цикла событий...

Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   //QThread::currentThread()->setPriority(QThread::HighestPriority); // and with this not a problem
   qApp->thread()->setPriority(QThread::HighestPriority);
   return a.exec();
}
 

Видимо с тех пор многое изменилось...
« Последнее редактирование: Февраль 23, 2010, 17:04 от SABROG » Записан
kkk777kkk
Гость
« Ответ #5 : Февраль 25, 2010, 10:03 »

решил таки воспользоваться винапи функциями:

Код:
#ifdef Q_WS_WIN
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
    SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
#endif

а если когда-то решится руководство на линух, то это будет RT линух и там это будет не так важно и будет достаточно (если вдруг понадобится) выставлять пририотеты только для потоков вторичных

спасибо за помощь
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.341 секунд. Запросов: 21.