Название: Периодическая обработка данных из другого потока Отправлено: CountZero от Март 16, 2017, 14:27 Добрый день.
Имеется следующая задача: из основного потока программы запускаются два потока. Первый поток в бесконечном цикле получает осуществляет запросы к внешнему устройству, получает от него данные, обрабатывает их и генерирует сигнал о том, что новые данные пришли. Второй поток должен получить данные из первого потока, выдать управляющий сигнал, и после этого выдача управляющих сигналов должна быть заблокирована на некоторое время, в зависимости от результатов обработки данных от первого потока. Собственно вопрос по реализации этой самой блокировки как ее сделать? Для экспериментов накидал следующий код: 1. Поток имитирующий получение данных от устройства. Код: MainThread::MainThread() 2. Поток имитирующий управляющий: Код: ControlThread::ControlThread() 3. Создание потока, настройка сигналов, слотов в основном: Код: threadControl = new QThread; В такой реализации у нас "управляющий" поток выдает сигналы с частотой опроса устройства - данные пришли, сигнал выдали. А требуется чтобы он на основании данных выдал сигнал, потом X секунд подождал (данные при этом можно обновлять, реакция не требуется), а через Х секунд началась новая итерация. Пробовал вариант со Sleep, но он естественно просто замораживает отработку, а сигналы приходят и после "разморозки" начинается отработка каждого блока из пришедших данных, а нужно отработать только по последним данным. Название: Re: Периодическая обработка данных из другого потока Отправлено: __Heaven__ от Март 17, 2017, 09:32 Не сильно разбирался в Вашем коде, но, кажется, вам должен подойти таймер, генерирующий сигналы на таймауте.
http://doc.qt.io/qt-5/qtimer.html#timeout Возможно будет достаточным заменить бесконечный цикл на него. Название: Re: Периодическая обработка данных из другого потока Отправлено: CountZero от Март 17, 2017, 10:04 Не сильно разбирался в Вашем коде, но, кажется, вам должен подойти таймер, генерирующий сигналы на таймауте. http://doc.qt.io/qt-5/qtimer.html#timeout Возможно будет достаточным заменить бесконечный цикл на него. Проблем с бесконечным циклом как раз нет, и его менять не надо. Суть как раз в том, что данные приходят и должны приходить с частотой большей чем частота реакции на данные. Менять надо было поведение второго потока, в котором цикла нет. Про QTimer и его timeout() естественно знаю, вопрос был как корректно организовать взаимодействие. Проблему уже решил самостоятельно. На самом деле все оказалось настолько очевидным, что даже странно, что сразу не пришло в голову. В следующем сообщении опишу решение. Название: Re: Периодическая обработка данных из другого потока Отправлено: CountZero от Март 17, 2017, 10:47 Проблема решена.
Для того чтобы решить задачу требуется добавить таймер в MainWindow, который и будет периодически запускать отработку второго процесса. В MainWindow: 1. Добавляем QTimer* tmr. 2. Добавляем в MainWindow слот SetTimer(int tm) в котором будем запускать таймер необходимой задержки командой tmr->start(tm); 3. Соединяем сигнал таймера tmr->timeout() со слотом process() второго процесса 4. Cоединяем сигнал delay(int tm) второго процесса со слотом SetTimer(int tm) В ControlThread: 1. Добавляем сигнал delay(int tm), 2. Убираем запуск process() из getPV(double data) 3. Добавляем в конце выполнения всей логики process() выработку сигнала delay(miliseconds) У нас получается этакое кольцо - таймер запускает process, process запускает таймер, для начального входа в этот цикл используется сигнал от нити started(), который запустит process() первый раз, чтобы все было нормально в конструкторе следует проинициализировать данные таким образом чтобы первый прогон process() без полученных данных отработал корректно. Код: MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) Код: void ControlThread::process() |