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

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

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: QTCPSocket в отдельном потоке.  (Прочитано 32112 раз)
stix357
Гость
« Ответ #15 : Декабрь 30, 2016, 11:55 »

Неверно.
Сначала создаётся объект.
Потом вызывается конструктор.
Всё есть.
Только заготовка. Благодаря опять-таки конструктору предка.
2) создать наследника от QThread и в нём в конструкторе сделать moveToThread(this). И в этом наследнике творите что хотите.
Не сочтите за наглость, но возможно вас не затруднит показать простенький работающий пример по вашему методу?
QTcpSocket в отдельном QThread
Если я правильно понял, то должно выглядеть примерно так:
Код
C++ (Qt)
ReadData::ReadData(QObject *parent) :
   QThread(parent)
{
m_Socket=new QTcpSocket(this);
moveToThread(this);
}
 
« Последнее редактирование: Декабрь 30, 2016, 13:19 от stix357 » Записан
Bepec
Гость
« Ответ #16 : Декабрь 30, 2016, 15:48 »

Вы не понимаете...
Вы сначала создаёте объект... потом перемещаете все слоты потока в самого себя Веселый Объект при этом у вас никуда не перемещается.

Примерчик. Самый примитив.
https://dl.dropboxusercontent.com/u/62712483/Temp.zip
Записан
stix357
Гость
« Ответ #17 : Январь 09, 2017, 14:47 »

Вы не понимаете...
Вы сначала создаёте объект... потом перемещаете все слоты потока в самого себя Веселый Объект при этом у вас никуда не перемещается.

Примерчик. Самый примитив.
https://dl.dropboxusercontent.com/u/62712483/Temp.zip
Благодарю, буду сравнивать и смотреть где напортачил. Руки пока не доходили.
Записан
stix357
Гость
« Ответ #18 : Январь 11, 2017, 07:23 »

Примерчик. Самый примитив.
https://dl.dropboxusercontent.com/u/62712483/Temp.zip
Вопрос возник:
если по вашему примеру
Код
C++ (Qt)
void SBThread::run()
{
   m_pTcpSocket = new QTcpSocket(this);
 
   connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
   connect(m_pTcpSocket, SIGNAL(disconnected()), SLOT(disconnected()));
   connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(readyRead()));
   connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(error(QAbstractSocket::SocketError)));
....
 
то что произойдет с распределением памяти при завершении void SBThread::run()?
выделенная память под m_pTcpSocket сама освободится или это надо делать ручками?
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #19 : Январь 11, 2017, 08:58 »

Объект сокета будет жить, пока жив класс потока. Создавай на стеке.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
stix357
Гость
« Ответ #20 : Январь 11, 2017, 09:21 »

Объект сокета будет жить, пока жив класс потока. Создавай на стеке.

Mмм, не понял фразу Создавай на стеке.

А если так?
Код
C++ (Qt)
void SBThread::run()
{
   QTcpSocket m_pTcpSocket;
 
   connect(&m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
   connect(&m_pTcpSocket, SIGNAL(disconnected()), SLOT(disconnected()));
   connect(&m_pTcpSocket, SIGNAL(readyRead()), SLOT(readyRead()));
   connect(&m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(error(QAbstractSocket::SocketError)));
....
 
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #21 : Январь 11, 2017, 09:24 »

Так объект сокета разрушится при выходе из метода run. Это и есть на стеке.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #22 : Январь 11, 2017, 09:25 »

Еще советую не наследоваться от QThread, а делать moveToThread. На форуме есть обсуждение данного совета со ссылками.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #23 : Январь 11, 2017, 09:35 »

Еще советую не наследоваться от QThread, а делать moveToThread. На форуме есть обсуждение данного совета со ссылками.

В доке написано что можно и так, и так Улыбающийся
http://doc.qt.io/qt-5/qthread.html#details

// You can use worker objects by moving them to the thread using QObject::moveToThread().
Код
C++ (Qt)
class Worker : public QObject
{
   Q_OBJECT
 
public slots:
   void doWork(const QString &parameter) {
       QString result;
       /* ... here is the expensive or blocking operation ... */
       emit resultReady(result);
   }
 
signals:
   void resultReady(const QString &result);
};
 
class Controller : public QObject
{
   Q_OBJECT
   QThread workerThread;
public:
   Controller() {
       Worker *worker = new Worker;
       worker->moveToThread(&workerThread);
       connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
       connect(this, &Controller::operate, worker, &Worker::doWork);
       connect(worker, &Worker::resultReady, this, &Controller::handleResults);
       workerThread.start();
   }
   ~Controller() {
       workerThread.quit();
       workerThread.wait();
   }
public slots:
   void handleResults(const QString &);
signals:
   void operate(const QString &);
};
 

// Another way to make code run in a separate thread, is to subclass QThread and reimplement run(). For example:
Код
C++ (Qt)
class WorkerThread : public QThread
{
   Q_OBJECT
   void run() Q_DECL_OVERRIDE {
       QString result;
       /* ... here is the expensive or blocking operation ... */
       emit resultReady(result);
   }
signals:
   void resultReady(const QString &s);
};
 
void MyObject::startWorkInAThread()
{
   WorkerThread *workerThread = new WorkerThread(this);
   connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
   connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
   workerThread->start();
}
 
Записан

Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #24 : Январь 11, 2017, 09:48 »

gil9red, ну, ясен пень, что не расстреляют за любой из способов. Просто я считаю, что наследование худший выбор. Вообще, ИМХО, лучше сначала все писать без потоков (на ассинхронке), а потом выносить в потоки нужные части, при этом moveToThread будет лучшим решением, чем изменение наследования.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
stix357
Гость
« Ответ #25 : Январь 11, 2017, 10:08 »

Объект сокета будет жить, пока жив класс потока. Создавай на стеке.
Вот я и думаю, как на утечки памяти не напороться ...
Ведь в случае
Код
C++ (Qt)
void SBThread::run()
{
   m_pTcpSocket = new QTcpSocket(this);
 
   connect(m_pTcpSocket, SIGNAL(connected()), SLOT(slotConnected()));
   connect(m_pTcpSocket, SIGNAL(disconnected()), SLOT(disconnected()));
   connect(m_pTcpSocket, SIGNAL(readyRead()), SLOT(readyRead()));
   connect(m_pTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(error(QAbstractSocket::SocketError)));
....
 
если я объекту SBThread потока дам команду quit(), то m_pTcpSocket  в памяти останется
но если потом скажу объекту SBThread - start(), то получается дубликат m_pTcpSocket будет создан .... а старый повиснет непонятно где.
Ладно, спасибо, буду экспереминтировать.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #26 : Январь 11, 2017, 10:14 »

Да, будет утечка. Либо в run проверку делай
Код
C++ (Qt)
if (!m_pTcpSocket) {
 m_pTcpSocket = new QTcpSocket(this);
}
 
Либо создавай на стеке.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
stix357
Гость
« Ответ #27 : Январь 11, 2017, 10:51 »

Да, будет утечка. Либо в run проверку делай
Код
C++ (Qt)
if (!m_pTcpSocket) {
 m_pTcpSocket = new QTcpSocket(this);
}
 
Либо создавай на стеке.
А при moveToThread что произойдет с объектом при завершении run() в двух вариантах?
1)
Код
C++ (Qt)
thread=new QThread(this);
socket=new QTcpSocket(this);
socket->moveToThread(thread);
 
2)
Код
C++ (Qt)
thread=new QThread(this);
QTcpSocket socket;
socket->moveToThread(thread);
 
Я просто не в курсе, как в QT утечки отследить, всего месяц с ним работаю.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #28 : Январь 11, 2017, 11:00 »

+1 за moveToThread. Переопределение run() нужно если дергается одна ф-ия и нет сигнал-слотового взаимодействия.
И указывать this у перемещаемого класса нельзя, перемещать можно только объекты без родителя (точнее, только топ-левел объект иерархии).
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #29 : Январь 11, 2017, 11:13 »

stix357, просто QTcpSocket смысла нет переносить в поток. Да и вообще, тебе тут поток не нужен, если работаешь с сокетом сигналами/слотами. Вот тебе пример с moveToThread.

Код
C++ (Qt)
class Calculator : public QObject
{
Q_OBJECT
signals:
 void finished (int sum);
public slots:
   void calculate () {
       int result = 0;
       for (int i = 0; i < 99999; ++i) {
               result += i;
       }
 
       emit finished (result);
   }
}
 
.............................
Calculator *calculator = new Calculator;
QThread *thread = new QThread
 
calculator->moveToThread (thread);
connect(thread, &QThread::started, calculator, &Calculator::calculate);
connect(thread, &QThread::finished, calculator, &Calculator::deleteLater);
 
connect(calculator, &Calculator::finished, [] (int result) {qDebug () << result;});
connect(calculator, &Calculator::finished, thread, &QThread::quit);
connect(calculator, &Calculator::destroyed, thread, &QThread::deleteLater);
thread->start();
 
 

Что непонятно, спрашивай. Писал в браузере - возможны ошибки.
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


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