How to use QNetworkAccessManager in multiple threads
-
hi,
I want to use QNetworkAccessManager in multiple threads,
my code is:void Test::run() { qDebug() << __FUNCTION__; QEventLoop loop; QTimer timer; timer.setSingleShot(true); QNetworkRequest request; request.setUrl(QUrl(this->link)); reply = networkManager->get(request); reply->setReadBufferSize(0); connect(reply, &QNetworkReply::readyRead, this, [this](){ QByteArray data = reply->readAll(); buffer.append(data); }, Qt::DirectConnection); connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, [this, &loop](QNetworkReply::NetworkError code){ loop.quit(); }, Qt::DirectConnection); connect(reply, &QNetworkReply::sslErrors, this, [this](const QList<QSslError> &errors){ for (auto error : errors) { qWarning() << error.errorString(); } reply->ignoreSslErrors(); }, Qt::DirectConnection); connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); timer.start(300000); loop.exec(); timer.disconnect(); loop.disconnect(); }
but I got some output:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QNetworkAccessManager(0x1a26fe50b80), parent's thread is QThread(0x1a270705560), current thread is QThread(0x1a270704ae0)
so, What is the way to use QNetworkAccessManager in multiple threads?
-
hi,
I want to use QNetworkAccessManager in multiple threads,
my code is:void Test::run() { qDebug() << __FUNCTION__; QEventLoop loop; QTimer timer; timer.setSingleShot(true); QNetworkRequest request; request.setUrl(QUrl(this->link)); reply = networkManager->get(request); reply->setReadBufferSize(0); connect(reply, &QNetworkReply::readyRead, this, [this](){ QByteArray data = reply->readAll(); buffer.append(data); }, Qt::DirectConnection); connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, [this, &loop](QNetworkReply::NetworkError code){ loop.quit(); }, Qt::DirectConnection); connect(reply, &QNetworkReply::sslErrors, this, [this](const QList<QSslError> &errors){ for (auto error : errors) { qWarning() << error.errorString(); } reply->ignoreSslErrors(); }, Qt::DirectConnection); connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); timer.start(300000); loop.exec(); timer.disconnect(); loop.disconnect(); }
but I got some output:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QNetworkAccessManager(0x1a26fe50b80), parent's thread is QThread(0x1a270705560), current thread is QThread(0x1a270704ae0)
so, What is the way to use QNetworkAccessManager in multiple threads?
-
hi,
I want to use QNetworkAccessManager in multiple threads,
my code is:void Test::run() { qDebug() << __FUNCTION__; QEventLoop loop; QTimer timer; timer.setSingleShot(true); QNetworkRequest request; request.setUrl(QUrl(this->link)); reply = networkManager->get(request); reply->setReadBufferSize(0); connect(reply, &QNetworkReply::readyRead, this, [this](){ QByteArray data = reply->readAll(); buffer.append(data); }, Qt::DirectConnection); connect(reply, QOverload<QNetworkReply::NetworkError>::of(&QNetworkReply::error), this, [this, &loop](QNetworkReply::NetworkError code){ loop.quit(); }, Qt::DirectConnection); connect(reply, &QNetworkReply::sslErrors, this, [this](const QList<QSslError> &errors){ for (auto error : errors) { qWarning() << error.errorString(); } reply->ignoreSslErrors(); }, Qt::DirectConnection); connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit())); timer.start(300000); loop.exec(); timer.disconnect(); loop.disconnect(); }
but I got some output:
QObject: Cannot create children for a parent that is in a different thread. (Parent is QNetworkAccessManager(0x1a26fe50b80), parent's thread is QThread(0x1a270705560), current thread is QThread(0x1a270704ae0)
so, What is the way to use QNetworkAccessManager in multiple threads?
@Mozzie
Hi.
I think the problem isn't the QNetworkAccessManager in QThread but where you have declared it in the QThread.
I guess QNetworkAccessManager is a member of thread or you have done new of it in the constructor.
I have seen this issue with other objects ... try to make a new of QNetworkAccessManager in run function. -
@Mozzie
Hi.
I think the problem isn't the QNetworkAccessManager in QThread but where you have declared it in the QThread.
I guess QNetworkAccessManager is a member of thread or you have done new of it in the constructor.
I have seen this issue with other objects ... try to make a new of QNetworkAccessManager in run function. -
right, and there is another question:
Will it be too resource intensive, or Will creating too many QNetworkAccessManager cause other problems? -
right, and there is another question:
Will it be too resource intensive, or Will creating too many QNetworkAccessManager cause other problems?@Mozzie
Sorry but I don't know, I have never needed of multiple instance of QNetworkAccessManager.
My answer is only linked to:
"Parent is QNetworkAccessManager(0x1a26fe50b80), parent's thread is QThread(0x1a270705560), current thread is QThread(0x1a270704ae0" -
@Mozzie
Sorry but I don't know, I have never needed of multiple instance of QNetworkAccessManager.
My answer is only linked to:
"Parent is QNetworkAccessManager(0x1a26fe50b80), parent's thread is QThread(0x1a270705560), current thread is QThread(0x1a270704ae0" -
what is the difference between asynchronous API and multi thread?
if I use asynchronous API and have a lot of request, when data is coming, will it block my gui thread?
@Mozzie said in How to use QNetworkAccessManager in multiple threads:
if I use asynchronous API and have a lot of request, when data is coming, will it block my gui thread?
No it will not block, that's the point of asynchronous apis.
Keep in mind, QNetWorkAccessManger is limited to 6 parallel get requests, if you send more, those will be queued and executed when one of the 6 running requests finishes. FIFO
[edit: Fixed number of parallel requests SGaist]
-
what is the difference between asynchronous API and multi thread?
if I use asynchronous API and have a lot of request, when data is coming, will it block my gui thread?
-
@Mozzie said in How to use QNetworkAccessManager in multiple threads:
if I use asynchronous API and have a lot of request, when data is coming, will it block my gui thread?
No it will not block, that's the point of asynchronous apis.
Keep in mind, QNetWorkAccessManger is limited to 6 parallel get requests, if you send more, those will be queued and executed when one of the 6 running requests finishes. FIFO
[edit: Fixed number of parallel requests SGaist]
@J-Hilk
sorry, I did not make it clear.
I mean, if use asyn apis, I need to use signal and slots, right?
so if I use Qt::QueueConnection, my data will be processed in the gui thread, if the process need a lot of time, will it block my gui thread?
or should I use Qt::DirectConnection? -
@J-Hilk
sorry, I did not make it clear.
I mean, if use asyn apis, I need to use signal and slots, right?
so if I use Qt::QueueConnection, my data will be processed in the gui thread, if the process need a lot of time, will it block my gui thread?
or should I use Qt::DirectConnection?@Mozzie
Auto, you should use Qt::AutoConnection, which is the default one.There are very very few situations where you as the developer have to force a connection time. You shouldn't run into it normally.
If data processing takes a long time, then yes, your Gui will be unresponsive. Thats where Threading would come into place then. But probably not the subclassing QThread method
-
@Mozzie
Auto, you should use Qt::AutoConnection, which is the default one.There are very very few situations where you as the developer have to force a connection time. You shouldn't run into it normally.
If data processing takes a long time, then yes, your Gui will be unresponsive. Thats where Threading would come into place then. But probably not the subclassing QThread method
@J-Hilk
thanks, but i still have some question.
as you said: Thats where Threading would come into place then.
so, I just need to use another thread to process my data?
and
even QNetWorkAccessManger is limited to 5 parallel get requests, It still can request multiple times in 1 second, so how to ensure that you can only request a few times a second by using async apis -
@J-Hilk
thanks, but i still have some question.
as you said: Thats where Threading would come into place then.
so, I just need to use another thread to process my data?
and
even QNetWorkAccessManger is limited to 5 parallel get requests, It still can request multiple times in 1 second, so how to ensure that you can only request a few times a second by using async apis@Mozzie said in How to use QNetworkAccessManager in multiple threads:
so, I just need to use another thread to process my data?
yes, if it's needed, does your processing really use 100+ ms of time (per requested data)?
even QNetWorkAccessManger is limited to 5 parallel get requests, It still can request multiple times in 1 second, so how to ensure that you can only request a few times a second by using async apis
yes they are processed one after the other, if you really do not want to automatically queue the requests, simply store your QNetworkReply pointers in a vector of size 5 and check (before the request) if any pointer is a nullptr
-
@Mozzie said in How to use QNetworkAccessManager in multiple threads:
so, I just need to use another thread to process my data?
yes, if it's needed, does your processing really use 100+ ms of time (per requested data)?
even QNetWorkAccessManger is limited to 5 parallel get requests, It still can request multiple times in 1 second, so how to ensure that you can only request a few times a second by using async apis
yes they are processed one after the other, if you really do not want to automatically queue the requests, simply store your QNetworkReply pointers in a vector of size 5 and check (before the request) if any pointer is a nullptr
-
Hi,
Just in case, currently it's 6 requests simultaneously.