2701
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Февраль 02, 2009, 19:29
|
вот, переписал по-другому: ab.h #ifndef AB_H #define AB_H #include <QThread> #include <QDebug> #include <QTimer>
class A : public QObject { Q_OBJECT signals: void sgFromA(); public slots: void slotA() {//слот где инициализируем таймер qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(slotA1())); timer->start(10); } void slotA1() {//слот где по таймеру выполняем емиттинг сигнала qWarning() << "A::slotA1() -> TID = " << QThread::currentThreadId(); emit sgFromA(); } void slotA2() {//слот который выполняется при выдаче классом В сигнала qWarning() << "A::slotA2() -> TID = " << QThread::currentThreadId(); } };
class B: public QObject { Q_OBJECT signals: void sgFromB(); public slots: void slotB() {//слот, который выполняется при выдаче классом А сигнала qWarning() << "B::slotB() -> TID = " << QThread::currentThreadId(); emit sgFromB(); } };
class ThA : public QThread { public: A *cA; ThA() { cA = new A; } protected: void run() { qWarning() << "running ThA::run() -> TID = " << QThread::currentThreadId(); cA->slotA(); exec(); } };
class ThB : public QThread { public: B *cB; ThB() { cB = new B; } protected: void run() { qWarning() << "running ThB::run() -> TID = " << QThread::currentThreadId(); exec(); } }; #endif // AB_H
так правильно (корректно) ?
|
|
|
2702
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Февраль 02, 2009, 18:27
|
Для начала обработки событий, в run() нужно выполнить QThread::exec(). ну у меня ж это есть! void run() { qWarning() << "running ThA::run() -> TID = " << QThread::currentThreadId(); cA->slotA(); exec(); }
forever - это и есть остановка итерации. Причём без условия выхода из цикла, так вообще нельзя. Для этого потока всё остальное кроме этого цикла выполняться не будет. это получается что если в A::slotA() будет вечный цикл, то до exec() очередь не дойдет? ----- хм... если так, то получается вообще замкнутый круг.. , т.е нереально реализоватьвообще вот эту идею: 1. Имеется подсистема А в приложении (которая является отдельным потоком) и которая "вечно" в цикле анализирует некий массив данных.... суть анализа заключается в получении данных (опросе) из неких удаленных девайсов и сравнении полученных значений с предыдущим шагом... и если значение отличается - то выдать сигнал! (т.е выдать сигнал, если данные изменились) 2, Имеется подсистема В в приложении (которая тоже является потоком) и которая "отлавливает" сигнал, полученный от подсистемы А и выполняет свой алгоритм! Необходимо, чтобы : 1. главный поток приложения был - отдельно 2. поток подсистемы А выполнялся - отдельно (и все методы класса А выполнялись в этом потоке) 3. поток подсистемы В выполнялся - отдельно (и все методы класса В выполнялись в этом потоке) т.е как минимум иметь три "вечно" работающих потока! я что-то уже растерян, не представляю как это уже реализовать!
|
|
|
2704
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Февраль 02, 2009, 16:25
|
хм... сделал так: void slotA() { //for (int i=0;i<5;++i) { // qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); // emit sgFromA(); //} forever { qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); emit sgFromA(); } }
но почему-то память жутко утекает о_О . вроде ж в этом примере не создаются никакие объекты!
|
|
|
2705
|
Qt / Работа с сетью / Re: Работа с потоками
|
: Февраль 02, 2009, 15:41
|
2 zayac_val , посмотри примерчик http://www.prog.org.ru/topic_8455_30.htmlтам в самом конце пример... если яправильно понял попробуй этот же пример, предварительно заккоментировав по очереди строчки: tB->cB->moveToThread(tB); tA->cA->moveToThread(tA);
и посмотри в чем разница ЗЫ: может пригодится ЗЫЗЫ: тока в этом примере память утекает куда-то
|
|
|
2706
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 30, 2009, 15:20
|
вроде получилось ab.h #ifndef AB_H #define AB_H #include <QThread> #include <QDebug>
class A : public QObject { Q_OBJECT signals: void sgFromA(); public slots: void slotA() { for (int i=0;i<5;++i) { qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); emit sgFromA(); } //forever { // qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); // emit sgFromA(); //} } void slotA2() { qWarning() << "A::slotA2() -> TID = " << QThread::currentThreadId(); } };
class B: public QObject { Q_OBJECT signals: void sgFromB(); public slots: void slotB() { qWarning() << "B::slotB() -> TID = " << QThread::currentThreadId(); emit sgFromB(); } };
class ThA : public QThread { public: A *cA; ThA() { cA = new A; } protected: void run() { qWarning() << "running ThA::run() -> TID = " << QThread::currentThreadId(); cA->slotA(); exec(); } };
class ThB : public QThread { public: B *cB; ThB() { cB = new B; } protected: void run() { qWarning() << "running ThB::run() -> TID = " << QThread::currentThreadId(); exec(); } };
#endif // AB_H
main.cpp #include <QtCore> #include <QCoreApplication> #include <QDebug>
#include "ab.h"
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); //qWarning() << "App TP:" << QThread::currentThread(); qWarning() << "Application -> TID = " << QThread::currentThreadId(); ThA *tA = new ThA; ThB *tB = new ThB; tB->cB->moveToThread(tB); tA->cA->moveToThread(tA); QObject::connect(tA->cA, SIGNAL(sgFromA()), tB->cB, SLOT(slotB()), Qt::QueuedConnection); QObject::connect(tB->cB, SIGNAL(sgFromB()), tA->cA, SLOT(slotA2()), Qt::QueuedConnection); tA->start(); tB->start(); return app.exec(); }
вывод: Application -> TID = 0x830 running ThA::run() -> TID = 0xe4 running ThB::run() -> TID = 0x730 A::slotA() -> TID = 0xe4 A::slotA() -> TID = 0xe4 B::slotB() -> TID = 0x730 A::slotA() -> TID = 0xe4 B::slotB() -> TID = 0x730 A::slotA() -> TID = 0xe4 B::slotB() -> TID = 0x730 A::slotA() -> TID = 0xe4 B::slotB() -> TID = 0x730 A::slotA2() -> TID = 0xe4 B::slotB() -> TID = 0x730 A::slotA2() -> TID = 0xe4 A::slotA2() -> TID = 0xe4 A::slotA2() -> TID = 0xe4 A::slotA2() -> TID = 0xe4 ^C
вроде все так как мне нужно - но я не уверен что это заработает, если в классе А написать так: void slotA() { //for (int i=0;i<5;++i) { // qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); // emit sgFromA(); //} forever { qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); emit sgFromA(); } }
|
|
|
2707
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 30, 2009, 13:29
|
но если пишу так: объекты: class A : public QObject { Q_OBJECT signals: void sgFromA(); public slots: void slotA() { qWarning() << "A::slotA() -> TID = " << QThread::currentThreadId(); emit sgFromA(); } private:
};
class B: public QObject { Q_OBJECT public slots: void slotB() { qWarning() << "B::slotB() -> TID = " << QThread::currentThreadId(); } private: };
class ThA : public QThread { public: A *cA; ThA() { } protected: void run() { qWarning() << "running ThA::run() -> TID = " << QThread::currentThreadId(); cA = new A; forever { sleep(1); cA->slotA(); } } };
class ThB : public QThread { public: B *cB; ThB() { } protected: void run() { qWarning() << "running ThB::run() -> TID = " << QThread::currentThreadId(); cB = new B; exec(); } };
main int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); //qWarning() << "App TP:" << QThread::currentThread(); qWarning() << "Application -> TID = " << QThread::currentThreadId(); ThA *tA = new ThA; ThB *tB = new ThB; app.connect(tA->cA, SIGNAL(sgFromA()), tB->cB, SLOT(slotB()), Qt::QueuedConnection); tA->start(); tB->start(); return app.exec(); }
то консоль выводит : Application -> TID = 0x864 running ThA::run() -> TID = 0x11c running ThB::run() -> TID = 0x348 A::slotA() -> TID = 0x11c A::slotA() -> TID = 0x11c A::slotA() -> TID = 0x11c A::slotA() -> TID = 0x11c A::slotA() -> TID = 0x11c A::slotA() -> TID = 0x11c ^C
т.е получается что не "ловится" или не емиттится сигнал A::sgFromA() слотом B::slotB()
|
|
|
2708
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 30, 2009, 12:49
|
в общем сделал я так: классы: class A : public QThread { Q_OBJECT signals: void sgFromA(); public slots: void slotA() {} protected: void run() { sleep(2); qWarning() << "A::run() -> TID = " << QThread::currentThreadId(); emit sgFromA(); exec(); } };
class B: public QThread { Q_OBJECT /* signals: void sgFromB(); */ public slots: void slotB() { qWarning() << "B::slotB() -> TID = " << QThread::currentThreadId(); } protected: void run() { qWarning() << "B::run() -> TID = " << QThread::currentThreadId(); exec(); } };
main int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); //qWarning() << "App TP:" << QThread::currentThread(); qWarning() << "Application -> TID = " << QThread::currentThreadId(); QThread *tA = new A; QThread *tB = new B; app.connect(tA, SIGNAL(sgFromA()), tB, SLOT(slotB()), Qt::QueuedConnection); tA->start(); tB->start(); return app.exec(); }
консоль мне выдала следующее: Application -> TID = 0xe84 B::run() -> TID = 0x7e4 A::run() -> TID = 0xb98 B::slotB() -> TID = 0xe84
т.е слот slotB выполнился в потоке main с TID = 0xe84 , НО мне нужно чтобы он выполнился в потоке B с TID = 0x7e4 ! как это можно сделать?
|
|
|
2711
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 30, 2009, 08:40
|
Доброго утра! Подсскажите, а есть ли возможность узнать в каком потоке выполняется та или иная функция? т.е например что-то типа: ThreadId = getCurrentThreadId() ... это я к тому, чтобы мне можно было вывести в консоль ID-ы тех потоков, которых я хочу (для проверки фунциклирования) я не нашел в ассистенте ничего такого.. есть только: в описании QObject: QThread * QObject::thread () const - но это не ID (не дескриптор потока) в описании QThread: Qt::HANDLE currentThreadId () - вот это наверное то что нужно!!!? только непонятно что та зип данных HANDLE : --- Platform-specific handle type for system objects. This is equivalent to void * on Windows and Mac OS X, and embedded Linux, and to unsigned long on X11. Warning: Using this type is not portable. --- т.е это unsigned long ? ЗЫ: т.к все-равно у меня в голове еще все смутно и концы с концами не сходятся!
|
|
|
2712
|
Qt / Дополнительные компоненты / Re: SingleApplication (qt4.4)
|
: Январь 29, 2009, 20:56
|
следить за клиентами по их пиду (всё-таки клиент и сервер выполняются на одной машине в единой сессии), но имеет ли смысл серверу вообще знать своих клиентов "в лицо"? 1. насчет единой сессии - я не знал 2. насчет одной машины тож не знал Зы: не вникал в суть Но пусть сервер все - же знает в лицо!
|
|
|
2713
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 29, 2009, 20:43
|
7. у тебя slotFunc1 НЕ слот. если вызвать slotFunc1 как функцию, она будет отрабатывать в вызывающем потоке. если вызвать slotFunc1 через событие, слот отработает в своём потоке (вызывающая точка находится в петле) это слот, просто я забыл написать: public slots: void slotFunc1();
3., 4. сигнализирование от петли событий не зависит - сигнализировать можно и без неё хм... а зачем тогда вообще вызывать exec() ? ----- и еще: если я оставлю ф-ю run() пустой, то получается что после вызова Z->start() поток сразу завершится, выдаст сигнал finished() и, если я сделаю так : connect(this, SIGNAL(finished()), this, SLOT(deleteLater())); то получается что сразу после старта - класс Z сразу завершится и нафик удалится!!!! Ёлки! И я тогда никогда не смогу воспользоваться вызовом слота slotFunc1() , который например теоретически может быть привязан к сигналу, исходящему от какого нить класса Y !
|
|
|
2714
|
Qt / Дополнительные компоненты / Re: SingleApplication (qt4.4)
|
: Январь 29, 2009, 20:23
|
будет ли полезной возможность отправлять сообщения от сервера клиенту(ам) (вроде броадкаста)? если имеется ввидо это: 1. клиент подключается к серверу 2. запрашивает у сервера какие то данные спорадически (не отключаясь после запроса - а поддерживая канал в коннекте) 3. сервер время от времени шлет ПОДКЛЮЧЕННОМУ клиенту данные спорадически (не отключая при этом клиента после передачи ему данных) то это оч нужно! (мне по крайней мере для моего "проекта") штобы был FullDuplex ЗЫ: и кстати, когда там xml-rpc под QT4 переделаете? оч нужно !!! (именно там нужен FULL DUPLEX)
|
|
|
2715
|
Qt / Общие вопросы / Re: Потоки, сигналы, слоты и потенциальные касяки если связать все это?
|
: Январь 29, 2009, 19:59
|
стоп! давайте тогда подитожим ! например я определяю класс как наследник QThread class Z: public QThread { signals: void signal1() public: Z(); ~Z(); void slotFunc1(); protected: void run(); }
Z::Z() { }
Z::~Z() { }
void Z::run() { exec();// !!! //тут какие нить действия (и даже может быть в "бесконечном" цикле) ... действие 1 ... действие 2 ... действие N }
void Z::slotFunc1() { //тут какие нить действия ... действие 1 ... действие 2 ... действие N //тут емиттим сигнал emit signal1(); }
теперь напишу то что я думаю как оно работает (на сей момент) + какие у меня непонятки Поправьте меня где неправ я! И напишите как работает! 1. после вызова из main Z->start() , функция run() начинает выполняться в другом потоке ! (т.е не в потоке main) Так?! 2. пока run() выполняется, у класса Z получаем статус: isRunning() и т.п! (т.е "выполняется")! Так?! 3. когда в функции run() выполняется вызов exec() - то разрешается цикл обработки сообщений! (т.е если после этого вызвать извне или изнутри класса слот slotFunc1() - то сигнал signal1() успешно сэмиттится!) Так? 4. если бы не было вызова exec() в теле функции run() - то при вызове слота действия бы выполнились, НО сигнал бы не сэммитился! Так? 5. после того как в теле функции run() вызвался exec() - то после exec() выполнятся ли действия (которые ниже exec() идут в ф-ции run() ) или выполнение run() остановится на exec() и будет висеть так пока не сделать Z->quit() ? 6. после завершения функции run() (допустим если прервать там цикл или если без цикла) - класс Z семиттит сигнал : finished ? Так? ---- 7. теперь вот что! если вызвать слот slotFunc1() извне класса Z или изнутри класса Z (но не из функции run()) - то содержимое слота slotFunc1() выполнится в потоке main или в том же потоке что и run() (т.е. не в main) ? 8. при вызове слота (только не из run()) и пока выполняются действия в слоте - то статус класса Z будет isRunning ? 9. при окончании выполнения слота slotFunc1() - сэемитится ли классом Z сигнал finished() ? 10. после выполнения в теле run() вызова exec() - статус класса всегда будет isRunning() ? 11. после выполнения Z->quit() класс Z сэемитит сигнал finished() и т.п ? Так? --------- вроде пока все непонятки что хочу узнать
|
|
|
|
|