PDA

View Full Version : Multithreading & GUI



qthread
30th July 2014, 20:03
Hello,

I'm trying to develop a Desktop application that will send multiple request to a website and store the response. i want to do the requests in a separate threat so that the GUI will be responsive. I tried to use QNetworkAccessManager with run,qtconcurrent and i was not able to get success in achieving my goal. Can you guys give me some advice or ideas how can i implement multithreading with QNetworkAccessManager

example algorithm:
for(int i=0;i<1000;i++)
{
//send HTTP request using QNetworkAccessManager

} // should not affect the gui !!!!!!

stampede
30th July 2014, 20:46
Have you tried to use QTimer with 0 interval ?


for(int i=0;i<1000;i++)
{
//send HTTP request using QNetworkAccessManager

} // should not affect the gui !!!!!!

// with QTimer:

void MyClass::sendRequest(){
// send request using QNAM
++_requestSent;
if (_requestSent < 1000 && !_abort){
QTimer::singleShot(0,this,SLOT(sendRequest()));
}
}
// will not affect the gui, timeouts will be processed as soon as all gui events have been processed

Btw. why do you need to send a thousand http requests ?

qthread
30th July 2014, 22:34
Thanks for helping :) . I need it for doing testing.

The app crashed with this error message:" Creating pipes for GWakeup: Too many open files".(with interval 500) Is that because of too many network connections?! (i'm testing it against server running in my Virtual machine).

stampede
30th July 2014, 22:42
The app crashed with this error message:" Creating pipes for GWakeup: Too many open files".(with interval 500) Is that because of too many network connections?!
Maybe it is the cause. Try to process next request when previous one finished (connect to QNetworkReply::finished () signal) instead of using a timer.

wysota
30th July 2014, 23:46
Sending network requests does not "affect the GUI". You can safely do them in the main thread. Using multiple threads with QNetworkAccessManager makes little sense.

qthread
31st July 2014, 09:18
Maybe it is the cause. Try to process next request when previous one finished (connect to QNetworkReply::finished () signal) instead of using a timer.
I want to send multiple requests. I think using 'finished' method will slow down my task.


Sending network requests does not "affect the GUI". You can safely do them in the main thread. Using multiple threads with QNetworkAccessManager makes little sense.
Sending network requests wont affect the gui but running for loop will.

wysota
31st July 2014, 09:42
I want to send multiple requests. I think using 'finished' method will slow down my task.
Why so?


Sending network requests wont affect the gui but running for loop will.
What for loop? :)

qthread
31st July 2014, 20:08
Why so?


What for loop? :)
If i use finished method, the next request have to wait for the previous one,right?!

I need a loop for sending multiple request,right?!

wysota
31st July 2014, 22:18
If i use finished method, the next request have to wait for the previous one,right?!
No, of course not. You schedule as many requests as you want and QNetworkAccessManager will execute them when the right time comes. As far as I remember it will be sending four requests at a time.


I need a loop for sending multiple request,right?!

No, but having the loop is ok as well. Scheduling 1000 requests should take just a couple of milliseconds.

qthread
1st August 2014, 17:15
No, of course not. You schedule as many requests as you want and QNetworkAccessManager will execute them when the right time comes. As far as I remember it will be sending four requests at a time.



No, but having the loop is ok as well. Scheduling 1000 requests should take just a couple of milliseconds.



Ok. Thanks for the info. But how can i prevent the loop from affecting my gui. For some reason, i am not able to run the QNAM in separate thread. Can you give tell me steps or sample snippet for achieving my task :)

wysota
2nd August 2014, 08:01
Ok. Thanks for the info. But how can i prevent the loop from affecting my gui.
It will not affect your GUI.


For some reason, i am not able to run the QNAM in separate thread.
You are probably not running an event loop in that thread.


Can you give tell me steps or sample snippet for achieving my task :)
Sure, just state what the actual task is :)

qthread
2nd August 2014, 11:23
It will not affect your GUI.


You are probably not running an event loop in that thread.


Sure, just state what the actual task is :)

I am new to qt. I am not able to find any good resource in multithreading. I just want to do fuzzing (https://en.wikipedia.org/wiki/Fuzz_testing) on web applictions which i was assigned to do testing.

Here is exactly what i wanted:
I need to send more than 1000 or 10,000 requests to a web application without affecting the GUI(i tried to run 10,000 request in main thread, it's affecting the gui, not able to access any other items). so i wanted to run the QNAM &loop in a separate thread or any other way in such a way that it should not affect the other tasks. Can you give me a sample snippet or tutorial links to achieve this :)

Thank you

anda_skoa
2nd August 2014, 15:29
One way to do it is to have a worker object and move it to a QThread



Worker *worker = new Worker(); // class derived from QObject

QThread *thread = new QThread();
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(start())); // Worker needs a slot that start the work
thread->start();


Cheers,
_

qthread
3rd August 2014, 20:29
One way to do it is to have a worker object and move it to a QThread



Worker *worker = new Worker(); // class derived from QObject

QThread *thread = new QThread();
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(start())); // Worker needs a slot that start the work
thread->start();


Cheers,
_

Thanks it worked for me :D

How can i distinguish the responses?! I'm sending 1000 requests.
I can use response->request().url() function to get the corresponding url. However i want to set a unique number for each request and display along with corresponding response. How to do that in QNAM?

anda_skoa
4th August 2014, 07:52
One option would be to have a mapping from the QNetworkReply pointer to your reference data, e.g. using QHash.

In your case where you only need a single number, it is probably quicker to just set this value as a dynamic property on the QNetworkReply object.
See QObject::setProperty().

Cheers,
_

wysota
4th August 2014, 09:18
Just remember that QNetworkReply is a QIODevice which in turn is a QObject thus accessing it from more than one thread is not safe. Push the object to the main thread before you try accessing it. The original thread will probably not try accessing the object after finished() is emitted but it is better to be safe than sorry.

Which of course doesn't negate the fact that there is probably no point in using any extra threads here..

qthread
22nd August 2014, 19:33
I will be thankful if anyone give me a sample snippet to distinguish each QNAM response from others ;)

anda_skoa
23rd August 2014, 11:20
Each request is handled by a QNetworkReply object. So each request has a different, distinguishable, pointer to a QNetworkReply instance.
Each instance has the QNetworkRequest that it was created for.



void MyClass::networkRequestFinished(QNetworkReply *reply)
{
qDebug() << "Request for" << reply->request().url() << "finished" << (reply->error() != QNetworkReply::NoError ? "with an error" : "without error");
}


Cheers,
_

qthread
24th August 2014, 08:23
Thanks :) is it possible to pass a unique value to QNAM and access them via QNetworkReply other than URL ?!

wysota
24th August 2014, 08:25
Thanks :) is it possible to pass a unique value to QNAM and access them via QNetworkReply other than URL ?!

What kind of unique value?

anda_skoa
24th August 2014, 09:05
Thanks :) is it possible to pass a unique value to QNAM and access them via QNetworkReply other than URL ?!
QNetworkReply is a QObject derived class, you can set any value as a dynamic property.
See QObject::setProperty.

Cheers,
_

qthread
24th August 2014, 10:34
What kind of unique value?
Strings. for example hello1, hello2

wysota
24th August 2014, 10:37
Strings. for example hello1, hello2

I was rather asking for the reason and meaning of those values rather than their datatype.