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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Таймеры и потоки  (Прочитано 8207 раз)
Vamireh
Гость
« : Август 22, 2013, 16:19 »

Нужно прочитать из файла список команд и выполнить их. Упрощенно имеются классы:
  • Window - главное окно
  • ScriptWorker:QObject - выполняет скрипт
  • Device:QObject - для работы с неким устройством

В Window по нажатию кнопки "выполнить скрипт":
Код:
QThread *thread = new QThread;
Worker* worker = new Worker;
worker->moveToThread(thread)
connect (thread->started, worker->execScript);
thread->start;

В Worker в методе execScript:
Код:
Device device = new Device;
foreach(commands)
    do current command;

Все работает, кроме чтения из COM портов. Класс Device читает данные из устройства по таймеру, который не работает, т.к. нужно где-то запустить QThread::exec();
Вопрос где его запускать в этой схеме работы или посоветуйте другую схему.
Записан
mutineer
Гость
« Ответ #1 : Август 22, 2013, 16:24 »

QThread::exec() запускается внутри дефолтной реализации QThread::run()
Записан
Vamireh
Гость
« Ответ #2 : Август 22, 2013, 16:26 »

QThread::exec() запускается внутри дефолтной реализации QThread::run()

Да, но тем не менее timerEvent() в классе Device не срабатывают
Записан
mutineer
Гость
« Ответ #3 : Август 22, 2013, 16:31 »

А когда он должен сработать?
Девайс создается в функции execScript и как долго живет?
Записан
Vamireh
Гость
« Ответ #4 : Август 22, 2013, 16:48 »

Да, девайс создается в execScript и живет все время выполнения этой функции. В execScript циклом проходится по всем командам и их выполняет, например:
- задать напряжение источника тока
- включить изделие
- минуту подождать
- выключить изделие
- сохранить снятые данные

в девайсе в конструкторе запускается таймер, по событию которого считываются данные и вносятся в массив. Так вот, изделие включается, ждется минута, изделие выключается, сохраняется пустой файл. При этом событие таймера ни разу на срабатывает.
Записан
mutineer
Гость
« Ответ #5 : Август 22, 2013, 16:50 »

А ожидание как реализовано?
Если всю эту минуту поток стоит внутри этой функции, то таймер не сможет вызвать timerEvent (поток за минуту ни разу не вернется в EventLoop)
Записан
Vamireh
Гость
« Ответ #6 : Август 22, 2013, 16:58 »

Ожидание - Sleep из WinAPI, или nanosleep под Linux. Да и дело не в задержки, мне кажется. Я так же ни одного ответа от устройств не получаю, если просто слать подготовительные операции без задержек. Если Device создать прямо в Window и управлять им вручную кнопками, то все работает, если что.
Записан
mutineer
Гость
« Ответ #7 : Август 22, 2013, 17:00 »

В слипе проблема. Чтобы отработал таймер потоку надо вернуться в EventLoop и оттуда вызвать обработчик события таймера. А поток спит внутри execScript и в EventLoop не возвращается
Записан
Vamireh
Гость
« Ответ #8 : Август 22, 2013, 17:08 »

В свое время для другого места программы создал функцию sleep, которая делит время сна на маленькие куски, между которыми выполняется QApplication::processEvents() чтобы не было заморозки интерфейса. Здесь это поможет? Проверить только завтра смогу
Записан
mutineer
Гость
« Ответ #9 : Август 22, 2013, 17:09 »

В принципе поможет, но возможно лучше будет запустить локальный EventLoop и запилить таймер, по которому он завершится
Записан
Vamireh
Гость
« Ответ #10 : Август 22, 2013, 18:02 »

ок, завтра проверю
Записан
Vamireh
Гость
« Ответ #11 : Август 23, 2013, 16:42 »

да, все работает спасибо. правда с парой нюансов, например, между командами нужно задержку сделать в 1000мс, с 500мс задержкой все равно не работает.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #12 : Август 23, 2013, 16:45 »

Ожидание - Sleep из WinAPI, или nanosleep под Linux. Да и дело не в задержки, мне кажется. Я так же ни одного ответа от устройств не получаю, если просто слать подготовительные операции без задержек. Если Device создать прямо в Window и управлять им вручную кнопками, то все работает, если что.
насчет задержки в потоках, юзайте соответствующие sleep'ы у вашего наследника QThread (msleep, usleep) - они будут кросплатформенными Улыбающийся
Записан

mutineer
Гость
« Ответ #13 : Август 23, 2013, 16:46 »

что именно не работает и что за задержка между командами?
Записан
Vamireh
Гость
« Ответ #14 : Август 23, 2013, 20:01 »

если между командами этого скрипта запускать QEventLoop на секунду, то все работает. если этого не делать или даже на полсекунды запустить, то... ну в общем PortMon чтение из портов фиксирует, но не сразу, а через несколько записей в порты, например, отправил команду, полсекунды евентлупа, отправил вторую команду, полсекунды евентлупа, отправил третью команду, получил ответ на первую команду.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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