crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )


  Ответ в проблема с потоками Thread в Qt
Введите ваше имя
Подтвердите код

Введите в поле код из 6 символов, отображенных в виде изображения. Если вы не можете прочитать код с изображения, нажмите на изображение для генерации нового кода.
Теги
Выровнять по центру
Ссылка на тему
Ссылка на сообщение
Скрытый текст
Сокращение
Код с подсветкой
Offtopic
 
Удалить форматирование
Спец. элементы
Шрифт
Размер
 
Цвет шрифта
 
Отменить ввод
Вернуть ввод
Полужирный
Курсив
Подчеркнутый
 
 
Смайлики
Вставить изображение
Вставить адрес электронной почты
Цитата
Код
Раскрывающийся текст
 
Увеличить отступ
По левому краю
По центру
По правому краю
Вставить список
Вставить список

Опции сообщения
 Включить смайлы?
Иконки сообщения
(Опционально)
                                
                                
  [ Без иконки ]
 


Последние 10 сообщений [ в обратном порядке ]
Сергей Дата 30.11.2010, 13:53
 
Цитата(xls @ 26.11.2010, 9:51) *
Привет.
Ваша проблема в том, что все вызовы connect связывают сигналы и слоты объектов, находящихся в одном потоке ( да, сам объект потока находится в том потоке, в котором он был создан ) и это вызывает соединение типа Qt::DirectConnection, а не желаемое Вам Qt::QueuedConnection.
Для того, чтобы реализовать желаемое поведение можно поступить следующим образом ( рассмотрим простейший случай - два потока ).
1. Создать дочерний поток (ДП).
2. Создать в дочернем потоке объект с сигналом "прогресс".
3. Связать сигнал дочернего потока "прогресс" с сигналом созданного объекта "прогресс".
4. Связать сигнал объекта со слотом главного потока.
5. Вызывать сигнал ДП.
Для дважды дочерний потока ( ДДП ) аналогично создается объект, он связывается с сигналом ДДП, а затем с сигналом ДП, он вызовет свой объект, который свяжется с главным потоком асинхронно.


Я наверное чего то не понял, но помоему в коде я так и делаю
Раскрывающийся текст
void MainWindow::on_pushButton_clicked()
{
    ThMain_1 *MAIN_1 = new ThMain_1;
    connect(MAIN_1,SIGNAL(progress(int)),this,SLOT(on_progressBar_valueChanged(int)));
    MAIN_1->start();
}

void MainWindow::on_progressBar_valueChanged(int value)
{
    ui->progressBar->setValue(value);
}


//2

void ThMain_1::run()
{
  ThSub_1 *THSUB_1 = new ThSub_1;
  connect(THSUB_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
  THSUB_1->start();
 }


//3
void ThSub_1::run()
{

    Th_1 *TH_1 = new Th_1;
    connect(TH_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
    TH_1->start();
}

//вычисления (для теста полставил вместо вычислений)

void Th_1::run()
{

    for (int i=1; i<=100; i++)
    {
     sleep(1);
     emit progress(i);
     }

 }
xls Дата 26.11.2010, 9:51
  Привет.
Ваша проблема в том, что все вызовы connect связывают сигналы и слоты объектов, находящихся в одном потоке ( да, сам объект потока находится в том потоке, в котором он был создан ) и это вызывает соединение типа Qt::DirectConnection, а не желаемое Вам Qt::QueuedConnection.
Для того, чтобы реализовать желаемое поведение можно поступить следующим образом ( рассмотрим простейший случай - два потока ).
1. Создать дочерний поток (ДП).
2. Создать в дочернем потоке объект с сигналом "прогресс".
3. Связать сигнал дочернего потока "прогресс" с сигналом созданного объекта "прогресс".
4. Связать сигнал объекта со слотом главного потока.
5. Вызывать сигнал ДП.
Для дважды дочерний потока ( ДДП ) аналогично создается объект, он связывается с сигналом ДДП, а затем с сигналом ДП, он вызовет свой объект, который свяжется с главным потоком асинхронно.
Iron Bug Дата 25.11.2010, 0:35
  читай про реализацию QT сигналов в многопоточных приложениях и проверяй области видимости. может, у тебя process банально разрушается до того момента, как его успеют вызвать, или ещё где-то какие-нибудь локальные переменные задействованы.
Сергей Дата 25.11.2010, 0:04
  Нет, в консоли отладки никаких сообщний нет, но вот что я приметил: выставив точки останова при отладке, получается так, что сигнал из
void Th_1::run()
{

    for (int i=1; i<=100; i++)
    {
     sleep(1);
      emit progress(100);
     }

 }


не попадает в
 
void ThSub_1::SetProgress_th_2(int progress)
{
  emit progress_th_2(progress);
}


либо наоборот последний не принимает сигнал. Как считаете, может ли это зависеть от конкретно операционной системы(сижу под Fedora 14).
Iron Bug Дата 24.11.2010, 18:06
  я не спец в QT, но есть предположение, что внутри обработки сигнала повторный вызов этого же сигнала просто "гасится". то есть, функция
void ThMain_1::SetProgress_th_2(int progress) 
{    
emit progress_th_2(progress);  
 }

просто ничего не выполняет, ибо всё это происходит внутри обработчика сигнала и сигнал после выхода тупо сбрасывается. попробуй использовать два сигнала - может, сработает.
kwisp Дата 24.11.2010, 17:34
  можно проверить что возвращает connect во всех случаях соединения.
в консоль предупреждения не сыпятся во время выполнения программы?
Сергей Дата 24.11.2010, 14:27
  Спасибо за совет, я переделал немного код, в результате получилось
void MainWindow::on_pushButton_clicked()
{
    ThMain_1 *MAIN_1 = new ThMain_1;
    connect(MAIN_1,SIGNAL(progress(int)),this,SLOT(on_progressBar_valueChanged(int)));
    MAIN_1->start();
}

void MainWindow::on_progressBar_valueChanged(int value)
{
    ui->progressBar->setValue(value);
}


//2

void ThMain_1::run()
{
  ThSub_1 *THSUB_1 = new ThSub_1;
  connect(THSUB_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
  THSUB_1->start();
 }


//3
void ThSub_1::run()
{

    Th_1 *TH_1 = new Th_1;
    connect(TH_1,SIGNAL(progress(int)),this,SIGNAL(progress(int)));
    TH_1->start();
}

//вычисления (для теста полставил вместо вычислений)

void Th_1::run()
{

    for (int i=1; i<=100; i++)
    {
     sleep(1);
     emit progress(i);
     }

 }


но не помогло, всё равно сигнал не доходит, Но если вычесления делать не в Th_1 а в предыдущем потоке то сигнал доходит.... вот как бы и продлема
kwisp Дата 24.11.2010, 11:05
 
Цитата(Гость_Сергей_* @ 24.11.2010, 10:50) *
 connect(THSUB_1,SIGNAL(progress_th_2(int)),this,SLOT(SetProgress_th_2(int)));  
...
void ThMain_1::SetProgress_th_2(int progress) 
{    
emit progress_th_2(progress);  
 }

сигналы можно напрямую друг с другом соединять.

Цитата(Гость_Сергей_* @ 24.11.2010, 10:50) *
TH_2->start(); 
connect(TH_2,SIGNAL(progress_2(int)),this,SLOT(SetProgress_th_2(int)))

может поток уже все "отработал"(уже вызвал сигнал, который остался без обработчика) и только потом произошло соединение.
попробуй эти строки местами поменять
Сергей Дата 24.11.2010, 10:50
  задача такая, нужно создать несколько потоков, в частности 3, причем чтобы из первого потока запускался второй, из второго третий, а в третьем производились вычисления.
информацию о состоянии вычислений третьего потока нужно вывести на progressBar формы.
я использую сигнально слотовые соединения т.е
запускаю первый поток:

void MainWindow::on_pushButton_clicked()
{
    ThMain_1 *MAIN_1 = new ThMain_1;
    MAIN_1->start();
    connect(MAIN_1,SIGNAL(progress_th_2(int)),this,SLOT(on_progressBar_2_valueChanged(int)));

}

void MainWindow::on_progressBar_2_valueChanged(int value)
{
    ui->progressBar_2->setValue(value);
}

запускаю второй поток: 
 void ThMain_1::run()
{
    ThSub_1 *THSUB_1 = new ThSub_1;
    THSUB_1->start();
    connect(THSUB_1,SIGNAL(progress_th_2(int)),this,SLOT(SetProgress_th_2(int)));
}

void ThMain_1::SetProgress_th_2(int progress)
 {
   emit progress_th_2(progress);
  }

запускаю третий поток
void ThSub_1::run()
{
th_2 *TH_2 = new th_2;
TH_2->start();
connect(TH_2,SIGNAL(progress_2(int)),this,SLOT(SetProgress_th_2(int)))
}

void ThSub_1::SetProgress_th_2(int progress)
{
  emit progress_th_2(progress);
}

произвожу в третьем потоке вычисления
void th_2::run()
{
    int __progress=0;
    double _result=0;
     for (int i=0; i<=199800; i++)
        {
          _result+=cos(atan(i));
          if (i%1998==0)
          {
              emit progress_2(++__progress);
          }
        }
}

и посылаю состояние вычислений через все потоки в форму.
но почему то не работает. Подскажите, в чем может быть поблема-ошибка.
Просмотр темы полностью (откроется в новом окне)
RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 5.7.2025, 2:42