Russian Qt Forum
Ноябрь 23, 2024, 10:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QThread + QTcpSocket + основной поток  (Прочитано 25714 раз)
Vexator
Гость
« Ответ #15 : Август 18, 2009, 09:41 »

Хм, подскажите, где я затупил?
после строчки (QThread)->run()
где в самом run() последней строкой идет exec()
выполнение кода никогда не произойдет... или вернее произойдет наверное когда "поток" завершиться...
почему после запуска обработчика exec() управление не возвращается?...

осознал свой косяк, запускать поток надо через start()  Смеющийся , но после этого вылезла проблема с QObject и детьми из другого потока ))) где то тут про это было, буду искать Улыбающийся
« Последнее редактирование: Август 18, 2009, 09:58 от Vexator » Записан
Vexator
Гость
« Ответ #16 : Август 18, 2009, 10:14 »

Все спасибо соседнему топику про QTcpServer в QThread
оставлю тут как заметку для тех кто натыкается на эти грабли:
при создании своего потока необходимо сделать следующее:
1) переопределить QThread, конструктор и метод run();
2) для орагнизации полноценного цикла обработки в конце метода run(), вызвать exec();
3) переместить обработку потока в сам поток  Смеющийся , для этого после создания потока вызвать
(мой класс потока)->moveToThread(мой класс потока);
4) после чего запустить обработку всего этого командой ->start()

если я где то не прав, ткните где Улыбающийся
Записан
boobsik
Гость
« Ответ #17 : Август 18, 2009, 10:29 »

я сделал setSocketDesctiptor после того, как привязал сигнал readyRead к слоту в потоке и обрабатываю сигнал processData, чтобы обработать данные

Код:
class MLNetThread : public QThread{
    Q_OBJECT
public:
    MLNetThread(int socketDesc, QObject *pParent = 0);
    void run();
signals:
    void processData(QByteArray *data);
private:
    int socketDescriptor;
    QByteArray *data;
    QTcpSocket *socket;
private slots:
    void readSocket();
};

Код:
MLNetThread::MLNetThread(int socketDesc, QObject* pParent):
        QThread(pParent){
    socketDescriptor = socketDesc;
}

void MLNetThread::run(){
    data = new QByteArray();
    socket = new QTcpSocket();
    connect(socket, SIGNAL(readyRead()), this , SLOT(readSocket()));
    socket->setSocketDescriptor(socketDescriptor);
    exec();
}

void MLNetThread::readSocket(){
    data->append(socket->readAll());
    emit processData(data);
}
Записан
boobsik
Гость
« Ответ #18 : Август 18, 2009, 10:32 »

Хм, подскажите, где я затупил?
после строчки (QThread)->run()
где в самом run() последней строкой идет exec()
выполнение кода никогда не произойдет... или вернее произойдет наверное когда "поток" завершиться...
почему после запуска обработчика exec() управление не возвращается?...

осознал свой косяк, запускать поток надо через start()  Смеющийся , но после этого вылезла проблема с QObject и детьми из другого потока ))) где то тут про это было, буду искать Улыбающийся
в самом классе QThread храни только указатели, а создавай обьекты в run и помни, что QThread сам по себе находится в другом потоке, так что не вызывай его функции напрямую, обрабатывай сигналы и все)
Записан
BRE
Гость
« Ответ #19 : Август 18, 2009, 10:47 »

в самом классе QThread храни только указатели, а создавай обьекты в run и помни, что QThread сам по себе находится в другом потоке, так что не вызывай его функции напрямую, обрабатывай сигналы и все)
Можно и локальными объектами пользоваться:
Код
C++ (Qt)
void MLNetThread::run(){
   QTcpSocket socket;
   connect(&socket, SIGNAL(readyRead()), this , SLOT(readSocket()));
   socket.setSocketDescriptor(socketDescriptor);
   exec();
}
 
Записан
boobsik
Гость
« Ответ #20 : Август 18, 2009, 11:08 »

вообще, я так понимаю, если хочешь, чтобы вся работа потока выполнялась непосредственно в потоке, то нет смысла определять какие либо методы, кроме run.. А уже непосредственно в run создаешь классы, к которым и от которых подключаешь сигналы из основного потока.. А сам QThread сделать минимальным)
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #21 : Август 18, 2009, 11:09 »

...и помни, что QThread сам по себе находится в другом потоке, так что не вызывай его функции напрямую...

Да? А где про такое пишут, что весь QThread (наследник QThread, я правильно понял?) находится в другом потоке? Всю жизнь только run был "началом" другого потока, а вот принадлежность методов QThread (наследника QThread) к другому или главному потоку зависела от способа вызова (вызов из главного или второстепенного потока).
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #22 : Август 18, 2009, 11:11 »

вообще, я так понимаю, если хочешь, чтобы вся работа потока выполнялась непосредственно в потоке, то нет смысла определять какие либо методы, кроме run.

Никакой проблемы в создании доп методов нет. Хочешь чтобы эти методы выполнялись в доп. потоке - вызывай их из него (из run)
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
boobsik
Гость
« Ответ #23 : Август 18, 2009, 11:13 »

...и помни, что QThread сам по себе находится в другом потоке, так что не вызывай его функции напрямую...

Да? А где про такое пишут, что весь QThread (наследник QThread, я правильно понял?) находится в другом потоке? Всю жизнь только run был "началом" другого потока, а вот принадлежность методов QThread (наследника QThread) к другому или главному потоку зависела от способа вызова (вызов из главного или второстепенного потока).
ну QThread созданный в основном потоке там и находится, а обьекты созданные в его методе run() находятся в потоке QThread, я видимо не так высказался товарищь джедай))
Вызывая методы класса находящегося в конкретном потоке мы добьемся их выполнения исключительно в том же самом потоке, что и класс(кроме статических методов)
« Последнее редактирование: Август 18, 2009, 11:15 от boobsik » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #24 : Август 18, 2009, 11:15 »

а обьекты созданные в его методе run() находятся в потоке QThread

Верно Улыбающийся
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
boobsik
Гость
« Ответ #25 : Август 18, 2009, 11:27 »

вообще, я так понимаю, если хочешь, чтобы вся работа потока выполнялась непосредственно в потоке, то нет смысла определять какие либо методы, кроме run.

Никакой проблемы в создании доп методов нет. Хочешь чтобы эти методы выполнялись в доп. потоке - вызывай их из него (из run)
ну попробуйте создать и вызвать из run() метод QThread, который принимать указатель на обьект созданный в run() и изменять его   Строит глазки просто методы в осоновном необходимы, для того чтоб изменять данные, верно?...
...работает) но всеравно изменяешь данные как правило если пришел сигнал что их получил) а если сигнал подключаешь непосредственно в QThread, то и обрабатываться данные будут в главном потоке.. Для того, чтобы работа происходила во внутреннем потоке необходимо подключать сигналы к обьектам потока... А то вдруг ты обрабатываешь данные во внешнем в то время как во внутреннем они изменились, лочить внутренний поток придется..
« Последнее редактирование: Август 18, 2009, 11:47 от boobsik » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #26 : Август 18, 2009, 13:37 »

Для этого нужно ознакомиться с методами синхронизации потоков и проблем никогда небудет. Сингалы\слоты, эвенты это, можно так сказать, способы "общения" между потоками. Но мне никто не запрещает "общаться" между потоками напрямую (естественно, синхронизировав при этом работу)
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Vexator
Гость
« Ответ #27 : Август 19, 2009, 01:35 »

а еще вопрос несколько не в тему, но около того, подскажите как правильно работает QMutex (ну и вообще мутексы)
как я понял (а возможно понял я не правильно), он ограничивает доступ к следующим за ним командам/данным, до тех пор пока не будет вызван unlock(). Если это так, тогда зачем создавать и использовать более одного экземпляра данного класса в приложении? когда может возникунть такая потребность?...
и к примеру задачка, есть у меня класс выполняющий обработку и хранение данных, сам экземпляр класса запущен в основном потоке (по крайней мере я так думаю, т.к. создан он в нем), указатели на него переданы в дочерние потоки, которые выполняют определенные взаимодействия с другими системами через сокеты (распределенные вычисления), и из этих потоков переодически необходимо вызывать этот класс для получения или передачи в него данных... вопрос, правильно ли будет использовать QMutex в самом классе (к примеру при вызове метода записи данных, блокировать эти саммые данные) и что произойдет в таком случае, если 2 потока вызовут этот метод "одновременно"?
Записан
boobsik
Гость
« Ответ #28 : Август 19, 2009, 01:48 »

и что произойдет в таком случае, если 2 потока вызовут этот метод "одновременно"?
When you call lock() in a thread, other threads that try to call lock() in the SAME PLACE will block until the thread that got the lock calls unlock()
Записан
Vexator
Гость
« Ответ #29 : Август 19, 2009, 01:59 »

и что произойдет в таком случае, если 2 потока вызовут этот метод "одновременно"?
When you call lock() in a thread, other threads that try to call lock() in the SAME PLACE will block until the thread that got the lock calls unlock()
спасибо Улыбающийся а то я этой надписи в асистенте не заметил
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.142 секунд. Запросов: 23.