[PyQt] QThread not forcibly terminating as expected
Andreas Pakulat
apaku at gmx.de
Sat Mar 3 09:17:39 GMT 2012
On 02.03.12 19:59:50, Brian Knudson wrote:
> Hello all,
>
> Apologies for the lengthy mail. The last paragraph is the important one, but everything else helps explain.
>
> I'm writing a PyQt interface for a networking system (3rd party application) via its API. The 3rd party API calls don't have a configurable timeout. So that my interface doesn't block, I've made those API calls run in a QThread. I've attached a timer to the thread & after a certain period of time (10 seconds in this case), I make the thread terminate itself using the very forceful terminate() function (I would happily use another if it would accomplish my goal of stopping execution NOW). I expect this would kill the API call, but it doesn't seem to. This happens when the API thinks a host is up, when, in fact, it is not, so it's locked waiting for socket connection/communication, but gets none - until it eventually times itself out some 60 seconds later.
Look at the QThread documentation for terminate(). One almost never
wants to call that function. But it clearly documents that the thread
might or might not terminate immediately.
http://qt-project.org/doc/qt-4.8/qthread.html#terminate
> In my thread class, I log when the run() function starts and when it stops. I also log when a timeout is reached & the terminate function is called. What I'm seeing is the run start, the timeout happen (which calls self.terminate()), and a good while later, the end of the run function is logged - which I wouldn't expect. I would expect the run function to cease doing anything when terminate() is called.
See above, you haven't read the API docs ;)
> I have the thread set to update the UI upon completion. When my app gets into this state, the UI widget this thread is trying to update is no longer updatable. The app is still responsive & other widgets will happily update themselves, but this one is locked until the thread finally ends.. at which point it can be updated again, so long as the API returns valid data.
Can you show some sample code for this, I don't quite understand what
you mean with "its not updatable" or "its locked"?
> I wonder if the problem is that the thread is blocked on a function call (the API call that uses sockets)... Does the API call need to unwind before the thread can terminate? If that's the case, any suggestions for how to get around this?
That would be a question for someone familiar with low-level IO like
sockets.
> I wouldn't much mind the lack of expected termination if it didn't lock up the widget, but it seems to (which is also surprising). At the end of the day, that's the important bit. Terminating the thread is only a way to get the widget to be responsive again sooner.
Can you leave out the network-system from your app, replace it with some
kind of busy-loop, i.e.
while(True):
time.sleep(.5)
Does that still lock up the widget until you terminate the thread? If so
please post a minimal example.
Andreas
More information about the PyQt
mailing list