[PyQt] QThread not forcibly terminating as expected
briank at pipelinefx.com
Sat Mar 3 03:59:50 GMT 2012
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.
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.
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.
I have set setTerminationEnabled to True (if that matters). I'm happy to post the code to my very generic worker thread class if needed
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?
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.
More information about the PyQt