Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Qt 4.4] Межпоточные сигналы, ожидание сигнала в потоке 
:(
    Опции темы
SABROG
Дата 9.9.2008, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



В голове творится полная каша, поэтому вопрашаю вашей помощи.

Абстрактная ситуация-пример. Жмем на кнопку - запускается класс на основе QThread, поток. Где-то в методе run() идут последовательные вызовы методов:

Код

void myThread::run()
{
        method1();
        method2()
        method3();
        method4();
}


Скажем method1() проверяет какой текст написан в QLineEdit, если написан нужный текст, то делает что-то и ждет сигнала, скажем сигнал returnPressed от QLineEdit. Как только сигнал был получен - переходим к методу method2, который делает уже другие действия, но также ждет определенного сигнала, после которого может перейти к method3(). Или если проверки в методах не удовлетворяют условиям, то цикл run() должен начинаться заново, или поток должен и вовсе завершаться. Методы буду добавляться, меняться местами и т.п. в процессе написания программы, возможно будут вынесены вообще в ECMAScript's. Также будет бесконечный метод (while (1)), который будет сканировать содержимое объекта другого потока и при наличии нужных изменений - выходить из метода с булевским флагом. На данном этапе не срабатывает межпотоковый QObject::connect, который задается в конструкторе класса, который раньше небыл наследником QThread и слоты срабатывали на сигналы, после наследования - перестали. Также перестала работать "затычка" в виде QEventLoop, которая выполняла роль "ожидалки сигнала" и бесконечный цикл выходил в слоте по loop.exit().

Для тех, кто хочет посоветовать избавиться от потока и сделать все в главном цикле. Вышеприведенная ситуация - упрощенная. Реальная задача без потока обойтись не может, т.к. используемый в программе компонент не достаточно гибок для подобной ситуации, в некоторых случаях не шлет никаких сигналов об изменении состояния объекта, в потоке это состояние периодически отслеживается.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Mal Hack
Дата 9.9.2008, 23:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 1
Всего: 261



SABROG, делал сейчас что-то подобное. Только у меня очередь из задач которые надо в потоках выполнять, плюс иногда один должен ждать другой.

Я сделал таким образом. Один из потоков стартует по сигналу завершения другого (это переход от одного к другому). То, что надо иногда ждать... Попробуй глянь QThreadPool. Мне он - не подошел, но для тебя вроде бы подходит, т.к. тебе надо сделать очередь 1-1-1-1, а у меня было сложнее.
PM ICQ   Вверх
SABROG
Дата 10.9.2008, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Так, ну почему не работали слоты я понял. Не работает без макроса Q_OBJECT.
Код

class MyThread::public QThread
{
    Q_OBJECT
public slots:
...
}


Причем до этого у меня был класс с этим макросом и наследовался от QObject'a. Когда добавил еще QThread, получилось так:

Код

class MyThread::public QObject, public QThread
{
    Q_OBJECT
public slots:
...
}


Компилер сгругался на QObject, типа QThread уже на базе QObject'a. Я тогда тупо зарубил и макрос убрал наследование. По идее сейчас и QEventLoop должен начать работать. Будем тестить.
---
Не, QEventLoop иногда вешает прогу намертво несмотря на то, что в отдельном потоке, а иногда просто крашит.
Патаюсь делать мутку с QTimer'ом в отдельном классе на базе QObject'a как тут предлагают , но проблема в том, что цикл получается одиночным для одного потока, а мне надо для каждого метода.

Это сообщение отредактировал(а) SABROG - 10.9.2008, 15:26


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



Вопрос, в принципе, подходит по эту тему.

Есть поток, который запускается по сигналу из основного потока. Все работает, но не каждый раз. То есть не после каждого emit запускается второй поток. Почему так может быть?
PM MAIL   Вверх
SABROG
Дата 9.1.2009, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Я недопонял. У тебя есть основной поток и дополнительный поток из которого ты запускаешь третий поток или у тебя тупо в основном потоке тред не запускается в слоте ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



В основном потоке:
Код

.............
this->connect( this, SIGNAL( pushToTray() ), this, SLOT( showTrayIcon() ), Qt::QueuedConnection );
.............
void RMainWindow::showTrayIcon(){
    this->setVisible( false );
    this->tray->setVisible( true );
    this->data.setTray( true );
    this->data.start(); //не всегда запускается
}

когда эмитится сигнал в основном потоке, то не всегда запускается второй поток.(всего 2 потока)
PM MAIL   Вверх
SABROG
Дата 9.1.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



А он успевает завершиться ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



да. В моей софтинке, если ее разворачиваешь из трея и работает вторичный поток, то некоторые кнопки неактивны. То есть завершение второго потока происходит до следующего запуска.
PM MAIL   Вверх
SABROG
Дата 9.1.2009, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



В консоль ничего не пишет ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



qDebug ?
не совсем понял вопрос
PM MAIL   Вверх
SABROG
Дата 9.1.2009, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Да, ядровый. Когда прогу с CONFIG += console собираешь


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



нет. Такого нету. Консоли нет. Только работа с БД
PM MAIL   Вверх
SABROG
Дата 9.1.2009, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Ну ты .pro файл временно отредактируй, чтобы глянуть. Может что-нить из этого вывестись, если есть ошибка:

Цитата

QThread::start: Failed to create thread
QThread::start: Failed to resume new thread



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 9.1.2009, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



изменил немного метод:
Код

void RMainWindow::showTrayIcon(){
    this->setVisible( false );
    this->tray->setVisible( true );
    this->data.setTray( true );
    qDebug() << "Thread starting\n";
    this->data.start();
    if ( !this->data.isRunning() ){
        qDebug() << "failed to start thread\n";
    }
}

Увидел, что в некоторые моменты бывает, что пишется
Код

Thread starting

но потом ничего не происходит. То есть раньше ругался на SQL, а теперь ничего не произошло...
нормально запустился:
user posted image

не запустился
user posted image
PM MAIL   Вверх
SABROG
Дата 10.1.2009, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



А поставь qDebug в начало метода run(). Может поток крашится где-то ?


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 10.1.2009, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



Вот мой метод run()
Может проблема была с msleep? Когда я использую wait вместо msleep, то вроде бы все работает...
Код

void RData::run(){
    qDebug() << ++counter;
    qDebug() << "Run starting\n";
    emit ready( false );
    emit unmarked( 0 );
    this->stopped = false;
    this->not_marked = 0;
    if ( this->tray ){
        while ( !this->stopped ){
            this->refresh();
            if ( this->stopped == true ) return;
            emit ready( true );
            emit unmarked( this->not_marked );
            //this->msleep( _UPD_TIME ); //
            this->wait( _UPD_TIME ); //
        }
    } else {
        this->refresh();
        emit ready( true );
        emit unmarked( this->not_marked );
    }
}

PM MAIL   Вверх
Acer
Дата 10.1.2009, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



Что-то я не понял как работает wait
Если использовать msleep, то есть вот такое сообщение:
Цитата

QThread: Destroyed while thread is still running

Как правильно сделать задержку в работе потока? Чтобы он работал не все время, а один раз в 60 секунд.
PM MAIL   Вверх
SABROG
Дата 10.1.2009, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(Acer @  10.1.2009,  10:49 Найти цитируемый пост)
Код

        while ( !this->stopped ){
            this->refresh();
            if ( this->stopped == true ) return;
            emit ready( true );
            emit unmarked( this->not_marked );
            //this->msleep( _UPD_TIME ); //
            this->wait( _UPD_TIME ); //
        }


А для чего тебе поток я понять не могу ? refresh() блокирует главный цикл ?
Почему бы тогда не сделать так. В слоте который сворачивает в трей запускаем QTimer, с нужной периодичностью он будет вызывать start() у потока, если тот не запущен.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Acer
Дата 10.1.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 5.9.2007
Где: UA::DN

Репутация: 15
Всего: 8



В refresh происходит обмен с базой.
Прога работает в трее. Второй поток нужен для того, чтобы при обмене с базой не зависал гуй и приложение можно было "достать" из трея в любой момент.
Сделал с QTimer. Все работает. Спасибо
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.3699 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.