Russian Qt Forum

Qt => Вопросы новичков => Тема начата: venom2013 от Сентябрь 04, 2013, 10:46



Название: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 10:46
Добрый день. Постановка задачи: есть несколько девайсов (количество переменное), необходимо создать поток для каждого и передавать туда данные на обработку.
Мой алгоритм реализации: при запуске программы создать поток для каждого девайса и назначить ему ид - имя девайса, например "0024". Когда я получаю сигнал от девайса, то смотрю на имя и передаю соответствующий поток.
Проблема в том что я не знаю как назначит ид (имя) потоку. Возможно вопрос глупый но опыта работы с потоками 0.     


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 10:52
Завести переменную в наследнике QThread. Или использовать QObject::objectName


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 10:54
Извините, а можно пример? Буду очень благодарен :)


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 10:54
Пример чего?
Пример наследования и добавления переменных - в любой книге по С++
Пример objectName в документации


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 11:04
Большое спасибо. Разбираюсь :)


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 12:21
Создаю поток в циклы:
Код:
 while (queryDevice.next()){

        MyThread *thread = new MyThread();
        thread->setObjectName(queryDevice.value(0).toString());
 }


Запрос возвращает n девайсов и каждому потоку назначаю имя соответственно девайсу. Как мне обратиться к потоку с изменим например "0024"?


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 12:35
сложить потоки в QMap, например. тогда можно и без setObjectName обойтись


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 13:11
а если сделать так:
Код:
    while (queryDevice.next()){
       
        MyThread *thread = new MyThread();
        threads.append(thread);
        thread->setObjectName(queryDevice.value(0).toString());
        connect(this, SIGNAL(StringSignal(QString , QString)), thread, SLOT(StringSlot(QString , QString)));
    }

......

    if(threads.at(0)=="0024")
        threads.at(0)->start();

это будет правильно?


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 13:17
нет, потому что MyThread вряд ли можно сравнить со строкой
используй threads.at(0)->objectName()


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 14:05
Большое спасибо!!!


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 17:00
Извините но не могли бы Вы подсказать.
Создаю потоки и слоты:
Код:
while (queryDevice.next()){

        MyThread *thread = new MyThread();
        threads.append(thread);
        thread->setObjectName(queryDevice.value(0).toString());
        connect(this, SIGNAL(StringSignal(QStringList)), thread, SLOT(messageFomMtHostTh(QStringList)));
        connect(thread, SIGNAL(StringSignalToMain(QString)), this, SLOT(slotWriteToMtHost(QString)));
        connect(thread, SIGNAL(logMtHost(QString)), this, SLOT(slotLogFromMtHost(QString)));
        connect(thread, SIGNAL(logPostgres(QString)), this, SLOT(slotLogFromPostgres(QString)));
        connect(thread, SIGNAL(logServer(QString)), this, SLOT(slotLogFromServer(QString)));
        connect(thread, SIGNAL(finished()), this, SLOT(slotThFinished()));
    }
Код:
            if(!threads.at(i)->isFinished())
                threads.at(i)->start();
            list.append(threads.at(i)->objectName());
            qDebug()<<threads.at(i)->objectName()<<thread()->currentThread();    //"0024" QThread(0x889c58)
            threads.at(i)->messageFomMtHostTh(list);


Код:
 virtual void run()
     {
         qDebug()<<currentThreadId()<<currentThread();   //0xf30 MyThread(0x7b62a0, name = "0024")
         //делаем что то в контексте нового потока
         exec(); //запускаем обработку очереди сообщений потока

     }

Запускается тот поток который мне нужно (функция run возвращает). А когда посылаю сообщения "threads.at(i)->messageFomMtHostTh(list);" в функцию

Код:
        thread()->currentThread()->objectName(); //пустая строка 
 

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


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 17:10
мне необходимо узнать какой поток завершился.  По окончанию таймера я посылаю сигнал
Код:
    timer->stop();
    emit  finished();

.....   
 if (thread()->isFinished())
            qDebug()<<thread()->currentThread();
ответ должен быть "MyThread(0x617680, name = "0024") "


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 17:17
threads.at(i)->messageFomMtHostTh(list);
при таком вызове выполнение происходит не в потоке из списка (который ты проименовал), а в текущем рабочем потоке (подозреваю что основной поток приложение), который не именован, поэтому и пустая строка вместо имени.

Ну это если я правильно понял этот твой сумбурный поток сознания

currentThread() - это статическая функция, она возвращает текущий поток, то есть поток, в котором сейчас происходит выполнение


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 17:21
да все правильно ты понял  :). Как вызвать поток из списка? Я целый день над этим сижу и уже не соображаю.


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 17:23
Как вызвать поток из списка?

Что значит "вызвать поток"?


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 17:27
извини за нубство. запустить функцию messageFomMtHostTh(list); в нужном мне потоки.
Я запускаю нужный мне поток, а как запустить messageFomMtHostTh(list) в этом потоке?
Код:
if(threads.at(0)->objectName()=="0024")
        threads.at(0)->start();


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: mutineer от Сентябрь 04, 2013, 17:30
Тебе нужно создать объект-наследник QObject, который реализует все твои сигналы-слоты, создать QThread и запустить его. Затем при помощи QObject::moveToThread() засунуть объект в поток и общаться с ним при помощи сигналов-слотов или QMetaObject::invokeMethod()


Название: Re: Передачи сигнала в определенный потоков.
Отправлено: venom2013 от Сентябрь 04, 2013, 17:35
Спасибо. Буду пробовать.