can time.sleep(secs) suspend QNetworkAccessManager does request asynchronously?
Asked Answered
I

3

5

QNetworkAccessManager can do requests asynchronously, and time.sleep(secs) can suspend the execution for the given number of seconds. I was confused by the code below. Is t2 here always greater than 10 seconds?

Without using time.sleep(secs) in the code here, the finished slot getWebPageSRC was called in fixed amount of time, roughly about 3 seconds.

I have tested this now a couple of times and found that t2 is always greater than 10 seconds. Can anyone explain why?

de myMethod(self):
    ...
    reply.finished.connect(self.getWebPageSRC)
    self.t=time.clock()
    time.sleep(10)

def getWebPageSRC(self):
    t2=time.clock()-self.t
    print(t2)

P.S. since QNAM doing its work asynchronously, I think it works in another thread ,thus has its own event loop , so does time.sleep(secs) suspend all the Qt event loop of all threads or just the event loop of the thread it within ? Does sleeping in main thread suspend all other threads ' event loop ?

Ictus answered 21/12, 2014 at 14:54 Comment(3)
Sorry, I made your question more proper English. ;-) Are you using pyqt or pyside? There isn't enough space to add both.Winifredwinikka
@lpapp Thank you, shamed for my poor English ...I am using PyQt,"There isn't enough space to add both."I don't understand what you mean here.Ictus
We can add maximum up to five tags to the question.Winifredwinikka
S
4

This question seems to be theoretical as it ought to never be a concern in the practice because that smells like fishy design or a quick workaround for a bug.

Having said that, the reason is relatively simple: when you start sleeping, the Qt event loop cannot do its work, so your slot cannot be processed from the event queue by the event loop before you wake up from your blocking sleep.

This would not be an issue if you, say, slept in another thread, although even that would be overly strange at first, but here you sleep in the thread (block) where the event is supposed to be handled asynchronously.

It does not make much sense in a Qt application to sleep after all. Qt is primarily meant for async operation, especially the QIODevice interfaces like QtNetwork.

When using Qt, forget about the existence of this statement:

time.sleep(10)

Whenever you consider to block to wait for the reply, you can use the sync API, although even that is not completely sync to be fair:

# 10000 msecs = 10 secs
myNetworkReply.waitForBytesWritten(10000)

I will probably even go further than that: I would probably avoid using Qt in a python application for anything else than strictly the UI. That is, all the rest can be achieved by python means, usually better and easier from a python application. I think you ought to focus on the GUI, but this is somewhat opinion based, for sure. Relevant alternatives would be asyncore, twisted, etc.

Sterilization answered 21/12, 2014 at 15:1 Comment(13)
yes,you are right .In QThread documentation says this :wait() and the sleep() functions should be unnecessary in general, since Qt is an event-driven framework. Instead of wait(), consider listening for the finished() signal. Instead of the sleep() functions, consider using QTimer.Ictus
@iMath: if the issue is resolved, then please select an answer.Winifredwinikka
I have complement the question , have not get any notification ?Ictus
@iMath: please never change your question, and no your QNAM does not run in another thread based on what you asked, but even if it was, sleep could not block another thread just as per the answer.Winifredwinikka
since QNAM doing its work asynchronously, I think it works in another thread ,is this right?Ictus
@iMath: no, it is wrong, but this is already well explained in any answers in here that it is the main thread. Please reread the answers carefully and try to grasp them. We have not written incorrect things.Winifredwinikka
Also, I suggest you forget about QtNetwork as per my answer. It does not make much sense to use it in a python application in my opinion since python has far more mature networking modules integrating better with the python world, also, without the C++ to Python wrapping overhead. But again, this is in the answer, too, just reiterating myself. So, pretty much everything you asked in this question should be forgotten, heh. It is a nice academic question, but has no real use in practice if you do things right.Winifredwinikka
@iMath: is there anything missing from the answer?Winifredwinikka
Thanks for your great help !!! I think I don't understand asynchronism, so posted this question. my final question here : Does sleeping in main thread suspend all other threads' event loop ?Ictus
The reason why I use QtNetwork here is I found it easy to calculate the download speed by void QNetworkReply::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) with QTimer, as for Python networking modules, I used Requests in my application ,while I cannot find a way to calculate the download speed by Requests, also ,since QNetworkAccessManager can do requests asynchronously so that the user interfere won't be freezed ,while if you are using Requests instead ,you have to wrap it in another thread, seems not convenient .Ictus
@iMath: no, it should not.Winifredwinikka
@iMath: have you tried the libraries that I mentioned to you? E.g. asyncore involves zero threading.Winifredwinikka
Thanks a lot! I have never used asyncore, corresponding to asyncio in py3.docs.python.org/3.4/library/asyncio.html#module-asyncio While I don't understand the Note at the beginning ,does that mean the module is not mature so the API could still be changed or it even could be removed from Python in the future ?Ictus
P
3

Regardless of QNAM doing its work asynchronously, it still operates in main thread. Stopping main thread for 10s blocks QNAM too.

Pruritus answered 21/12, 2014 at 15:2 Comment(3)
since QNAM doing its work asynchronously, I think it works in another thread ,thus has its own event loop , so does time.sleep(secs) suspend all the Qt event loop of all threads or just the event loop of the thread it within ? Does sleeping in main thread suspend all other threads ' event loop ?Ictus
No it does not work in another thread unless you explicitly put it into.Pruritus
Thank you, does time.sleep(secs) suspend all the Qt event loop of all threads or just the event loop of the thread it within ? Does sleeping in main thread suspend all other threads ' event loop ?Ictus
E
2

It's true that QNetworkAccessManager can do requests asynchronously but they all get executed in the application main thread. So when you call

time.sleep(10)

The main thread is blocked for 10 seconds and during this blocking nothing else is done. That's because QNetworkAccessManager here is not in an other thread.

Electroanalysis answered 21/12, 2014 at 15:2 Comment(4)
since QNAM doing its work asynchronously, I think it works in another thread ,thus has its own event loop , so does time.sleep(secs) suspend all the Qt event loop of all threads or just the event loop of the thread it within ? Does sleeping in main thread suspend all other threads ' event loop ?Ictus
@Ictus Working asynchronously does not mean that it has it's own event loop. Many objects can act asynchronously in the main event loop using signals and slots. Also QNAM does not live in an other thread. So here blocking the main event loop results in blocking the QNAM.Electroanalysis
Thank you, does time.sleep(secs) suspend all the Qt event loop of all threads or just the event loop of the thread it within ? Does sleeping in main thread suspend all other threads ' event loop ?Ictus
@Ictus time.sleep(secs) just suspends the event loop of it's thread (Here just main event loop). So if you make any other threads, they are not affected and continue to run. Sleeping in main thread just suspends the main thread.Electroanalysis

© 2022 - 2024 — McMap. All rights reserved.