Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [qt] пересылка данных между потоками 
:(
    Опции темы
gordmiand
Дата 19.6.2010, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



Есть 3 потока:
1. основной (Mainwindow) 
2. поток Potok1
3. поток Potok2

Суть следующая: в Potok1 данные задаются, затем они же используются в Potok2, после чего данные этого Potok2 отображаются в основном потоке...
Как передать данные (например переменную param) из потока в поток (чтобы в Potok2 можно было прочитать param из Potok1)? подскажите пож-та на моем примере...

Код

   /////////////////////////////////////////////////Mainwindow.cpp
  pt1 = new  Potok1;
  pt1->start();

  pt2 = new  Potok2;
  pt2->start();

         connect(pt2, SIGNAL(DataFromPotok2()), this, SLOT(GetData()) );
....................

void MainWindow::GetData()
{
        ui->lineEdit->setText(QString::number( pt2->prm )) ;
}

///////////////////////////////////////////////////////Potok1.cpp
void Potok1::run()
{
     param=11;

    ???
}
//////////////////////////////////////////////////////Potok2.cpp

Potok2::Potok2()
{
        exz_p1 = new Potok1;
}

///////////////////////////////////////////////////////////////

void Potok2::run()
{
          prm =  exz_p1->param+1;  //Не получается, ответ = [U]0[/U] +1; 

          emit  DataFromPotok2();
}



p.s. (не основное) - как запустить один поток из другого? если в примере выше я переносу запуск Potok2  (pt2 = new  Potok2;  pt2->start();) из Mainwindow в конструктор Potok1, то сразу после запуска приложения "программа неожиданно завершится с кодом...."


Это сообщение отредактировал(а) gordmiand - 19.6.2010, 21:09
PM MAIL   Вверх
gordmiand
Дата 20.6.2010, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



 smile 
неужели никто не передавал данные из потока в поток (из одного метода run в другой)? поясните пож-та на примере выше как это осуществить...
заранее спасибо всем за содержательные ответы...
PM MAIL   Вверх
borisbn
Дата 20.6.2010, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 48
Всего: 135



Если данных немного то передавай их в параметрах сигнала (сигнал не обязательно должен быть без параметров).
Если данных много, то создай структуру или класс для их хранения, выдели под них память в одном потоке через new, положи этот указатель в QSharedPointer и передай его в параметрах сигнала в другой поток. Об удалении (delete) этой структуры можешь не беспокоиться.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 20.6.2010, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



borisbn:  мне нужно передавать массив типа char mas[200][2000]...подскажите пож-та на моем примерчике (см. выше) как это проще всего сделать... буду ооочень признателен...
у меня что-то ну никак не получается из метода run потока potok1 испускать сигнал с параметром (т.е. моим массивом данных) и  принимать его в методе run (???) потока Potok2...
PM MAIL   Вверх
borisbn
Дата 21.6.2010, 08:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 48
Всего: 135



Массив char[][] передать, скорее всего, не получится. Можно скопировать его в один вектор или вектор векторов и уже этот объект передать в сигнале
Код

class Potok1
{
...
signals:
    void onNewData( const std::vector< char > data );
...
    void run()
    {
        char mas[ 200 ][ 200 ];
        ...
        std::vector< char > v;
        for ( int y = 0; y < 200; y++ )
            for ( int x = 0; x < 200; x++ )
                v.push_back( mas[ y ] [ x ] );
        emit onNewData( v );
    }
};

Цитата(gordmiand @  20.6.2010,  21:40 Найти цитируемый пост)
и  принимать его в методе run (???) потока Potok2...

а вот принимать его нужно в специальном слоте, а не в run.
Код

class Potok2
{
...
public slots:
    void onNewData( const std::vector< char > data )
    {
        char mas[ 200 ][ 200 ];
        for ( int y = 0; y < 200; y++ )
            for ( int x = 0; x < 200; x++ )
                mas[ y ][ x ] = v.at( y * 200 + x );
        ...
    }
};

не забудь connect'нуть potok1::onNewData с potok2::onNewData


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 21.6.2010, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



мне в принципе все ясно – в сигнале onNewData потока Potok1 нужный массив с данными копируется в вектор, а затем сигнал испускается  с этим вектором в качестве параметра. В потоке Potok2 слот onNewData принимает данные от сигнала onNewData потока Potok1 (в его слоте onNewData неизвестно v (Вы наверное просто забыли его объявить))  и записывает уже в свой массив mas[][]…

А где именно  в потоке Potok2 надо “connect'нуть potok1::onNewData с potok2::onNewData”?
Мне надо иметь возможность пользоваться этим массивом-вектором от Potok1 в методе run потока Potok2…



И почему в моем примере (в самом начале этой темы) не было нужды передавать переменную prm потока Potok2 в качестве параметра его сигнала DataFromPotok2(), испускаемого из run(), хотя значение этой переменной будет прекрасно видно в слоте GetData() (соединенного с сигналом DataFromPotok2()) главного потока…

PM MAIL   Вверх
gordmiand
Дата 21.6.2010, 20:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



что-то я затерялся между потоками....
Код

 Potok1 *pt1;
 Potok2 *pt2;
 public slots:
        void GetData();

                                    MainWindow-конструктор:
{
     pt1 = new  Potok1;
     pt1->start();

         pt2 = new  Potok2;
         pt2->start();

         connect(pt2, SIGNAL(DataFromPotok2()), this, SLOT(GetData()) );
}
//////////////////////////////////////////////////////////////////////////////////////////////////////

void MainWindow::GetData()
{
        ui->le->setText(QString::number( pt2->prm )) ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
class Potok1: public QThread
{
    Q_OBJECT
public:
    Potok1();
    Potok2 *exz_pt2;
    int param;
    void run();

signals:
     void sign1(int par1);
};
////////////////////////////////////////////////////////////////////////////////////////////////////
void Potok1::run()
{
        param=11;                        // например хочу это число передать в Potok2
        emit sign1(param);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
class Potok2: public QThread
{
     Q_OBJECT
public:
    Potok2();
     void run();
     Potok1 *exz_p1;
     int prm;

 public slots:
     void slot1(int sl)
     {
          prm=sl;
     }

signals:
     void DataFromPotok2();

};
//////////////////////////////////////////////////////////////////////////////////////////////////
Potok2::Potok2()
{
        exz_p1 = new Potok1;
}
/////////////////////////////////////////////////////////////////////////////////////
void Potok2::run()
{
            connect(exz_p1, SIGNAL(sign1(int)), this , SLOT(slot1(int)));

        //  prm = 5;        // exz_p1->param;//+1;

            emit  DataFromPotok2(  );
}

 ответ = 0...

подскажите пож-та на этом примере что тут неправильно и как будет верно наиболее простым способом?

PM MAIL   Вверх
gordmiand
Дата 22.6.2010, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



 smile 
подскажите пож-та что у меня неверно в вышеприведенном примере и как будет правильно?
уже замучился с этими потоками, а сделать обмен данными между потоками ооочень надо......а на таком примерчике глядишь и разобрался бы...

Это сообщение отредактировал(а) gordmiand - 22.6.2010, 21:33
PM MAIL   Вверх
gordmiand
  Дата 23.6.2010, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



borisbn: хорошо, но в Вашем примере в  потоке Potok2 данные, считанные из Potok1 (через его сигнал) в слоте onNewData (массив mas) будут доступны только в этом слоте...а
 как сделать так, чтобы они (данные от Potok1) были доступны для использования в run-е данного Potok2-потока??
подскажите пож-та на Вашем приведенном выше примере...буду ооочень признателен... smile 
PM MAIL   Вверх
borisbn
Дата 23.6.2010, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 48
Всего: 135



Код

class Potok2
{
...
    QMutex m_mutex;
    int m_mas[ 200 ][ 200 ];
public slots:
    void onNewData( const std::vector< char > data )
    {
        QMutexLocker locker( &m_mutex );
        for ( int y = 0; y < 200; y++ )
            for ( int x = 0; x < 200; x++ )
                m_mas[ y ][ x ] = v.at( y * 200 + x );
        ...
    }
    void run()
    {
        ...
        m_mutex.lock();
        // работа с m_mas
        m_mutex.unlock();
    }
};



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 23.6.2010, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



спасибо...
по поводу мьютекса - методы lock и unlоck я знаю, а зачем нужен
Код

  QMutexLocker locker( &m_mutex );  ???

PM MAIL   Вверх
borisbn
Дата 23.6.2010, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 48
Всего: 135



QMutexLocker - это класс, который делает lock  Qmutex'а, который передан ему в конструкторе, и unlock оного в деструкторе, т.е. там, где этот класс разрушается - заканчивается область видимости этого объекта.
Реализация QMutexLocker примерно такая:
Код

QMutexLocker::QMutexLocker( QMutex * m )
    : m_m( m )
{
    m->lock();
}
QMutexLocker::~QMutexLocker()
{
    m_m->unlock();
}

при этом заметь, что объект QMutexLocker locker( &m_mutex ); "живёт" пока не закончится выполнение функция onNewData


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
gordmiand
Дата 23.6.2010, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: нет
Всего: 0



 smile 
то есть получается, что "QMutexLocker - это класс, который делает lock  Qmutex'а, который передан ему в конструкторе, и unlock оного в деструкторе,"
в то же время вдобавок к этому в программе делаем
 
Код

     m_mutex.lock();
        // работа с m_mas
        m_mutex.unlock();

получается 2 раза делаем lock/ unlock  одного и того же мутекса, только разными способами - явно и с помощью спец. класса?
PM MAIL   Вверх
borisbn
Дата 24.6.2010, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 48
Всего: 135



Всё правильно. В функции onNewData необходимо залочить m_mas до конца выполнения функции, где и вызывается деструктор QMutexLocker'а, а в run нужно залочить только на время доступа к данным, а потом отпустить. Можно было и в функции onNewData сделать lock/unlock и в run сделать отдельную область видимости { QMutexLocker ... }
Я просто показал тебе оба варианта


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

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

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


 




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


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

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