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

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

Страниц: [1] 2 3 ... 5   Вниз
  Печать  
Автор Тема: Не отрабатывает QTimer::timeout()  (Прочитано 30759 раз)
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« : Октябрь 03, 2015, 23:35 »

Qt 5.5, Windows 8/Server 2012.
Имею следующий код в наследнике QThread:

Код
C++ (Qt)
void Thread::step()
{
   if (!m_printed) {
       m_printed = true;
       qDebug() << "step()" << QThread::currentThreadId();
   }
}
 
void Thread::run()
{
   qDebug() << "run()" << QThread::currentThreadId();
   m_printed = false;
 
   QTimer idle;
   connect(&idle, &QTimer::timeout, this, &Thread::step);
   idle.start(1);
   QThread::run();
}
На "обычных" (i7, i5, виртуалки) компах код работает ожидаемо - сколько потоков создано, столько же и отрабатываний в step(), причем вне зависимости от количества созданных потоков n (проверял для n <= 20). На серверных же двухпроцессорных Xeon с общим количеством ядер = 40 уже начиная с 16 потоков количество вызовов step() становится на 3-4 раза меньше, чем запущено потоков. Что это может быть?
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #1 : Октябрь 03, 2015, 23:59 »

1. Почему таймер создается как локальная переменная?
2. Зачем нужен вызов QThread::run(); ?
3. Какой таймаут у таймера? Предположение - таймер разрушается раньше, чем успевает эмитировать сигнал.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #2 : Октябрь 04, 2015, 00:27 »

1. Почему таймер создается как локальная переменная?
Почему - нет? Зачем ему быть переменной класса или чем-то ещё?
2. Зачем нужен вызов QThread::run(); ?
Для запуска цикла обработки событий внутри потока.
3. Какой таймаут у таймера? Предположение - таймер разрушается раньше, чем успевает эмитировать сигнал.
Таймаут 1 мс. Таймер не разрушается - он существует пока выполняется QThread::run(), то есть на протяжении всего времени жизни самого Thread.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Октябрь 04, 2015, 00:32 »

1. Почему таймер создается как локальная переменная?
А почему нет? Улыбающийся
Таймер будет жить все время работы нитки (выполнения run), а потом автоматически разрушиться.

2. Зачем нужен вызов QThread::run(); ?
Он запускает обработку очереди событий.

3. Какой таймаут у таймера?
1 мс.

Предположение - таймер разрушается раньше, чем успевает эмитировать сигнал.
Как уже писал выше, таймеры живут все время работы нитки.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Октябрь 04, 2015, 00:33 »

Дуплет. Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Октябрь 04, 2015, 00:35 »

количество вызовов step() становится на 3-4 раза меньше, чем запущено потоков. Что это может быть?
А нитки, в которых не сработали потоки, продолжают работать?
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #6 : Октябрь 04, 2015, 00:39 »

Дуплет. Улыбающийся
Причём, почти дословный Улыбающийся
А нитки, в которых не сработали потоки, продолжают работать?
Да, работают нормально. Да и те, которые "корявые" работают тоже - другие события они обрабатывают. Только таймерные не хотят.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Октябрь 04, 2015, 00:45 »

Попробуйте устанавливать интервал и запускать таймер раздельно:
Код
C++ (Qt)
setInterval( 1 );
start();
 
« Последнее редактирование: Октябрь 04, 2015, 00:48 от Old » Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #8 : Октябрь 04, 2015, 00:50 »

Я имел в виду последнюю строку в void Thread::run() . Там у вас QThread::run () что запускает? Просто всего кода не видно.
Hyperthreading активен, кстати?
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #9 : Октябрь 04, 2015, 00:51 »

Я имел в виду последнюю строку в void Thread::run() . Там у вас QThread::run () что запускает?
Он запускает QThread::exec().
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #10 : Октябрь 04, 2015, 00:56 »

http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/

Посмотрите Usage 1-2 , кажется, там похожая проблема решается.
« Последнее редактирование: Октябрь 04, 2015, 00:58 от Racheengel » Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #11 : Октябрь 04, 2015, 00:57 »

Попробуйте устанавливать интервал и запускать таймер раздельно:
Ожидаемо не помогло Грустный
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #12 : Октябрь 04, 2015, 00:59 »

Я имел в виду последнюю строку в void Thread::run() . Там у вас QThread::run () что запускает?
Он запускает QThread::exec().

В чем смысл? По хорошему надо бы переопределить run () и стартовать через exec (), а не наоборот.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Октябрь 04, 2015, 01:01 »

В чем смысл? По хорошему надо бы переопределить run () и стартовать через exec (), а не наоборот.
Нитка стартует через start, exec запускает eventloop.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #14 : Октябрь 04, 2015, 01:03 »

http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
Посмотрите Usage 1-2 , кажется, там похожая проблема решается.
Нет, там решается другая проблема, связанная с тем, что там события таймера отрабатывают в основном потоке, а не в пользовательском. У меня этой проблемы нет.

В чем смысл? По хорошему надо бы переопределить run () и стартовать через exec (), а не наоборот.
Не заморачивайся. Можно заменить QThread::run() на exec() ничего не изменится, суть проблемы не в этом:
Код
C++ (Qt)
void QThread::run()
{
   (void) exec();
}
« Последнее редактирование: Октябрь 04, 2015, 01:05 от xokc » Записан
Страниц: [1] 2 3 ... 5   Вверх
  Печать  
 
Перейти в:  


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