I have a queue and an event. I would like to exit the loop when the event is set to True, however there is a queue.get() in the loop which blocks until there is something in it.
How can I abort the waiting of the self._commandQueue.get() when the closeEvent Event flag is set?
Note: I want to avoid depending on the blocking nature of the queue and want to block based on the condition of the queue and the eventflag
def _execute(self):
while not self._closeEvent.isSet():
nextCommand = self._commandQueue.get()
self._commandExecutor.execute(nextCommand)
self._commandQueue.task_done()
解决方案
You would need something like the Windows WaitForMultipleObjects() call, but the python event and queue API don't offer such a beast (but you could use win32api to use that if you are strictly windows), so if you really need BOTH event sources to be checked in parallel, the answer is 'you cannot without polling (or monkey patching the Event class to allow it)'.
But if you are a bit more flexible, you can arrange something like it, by redefining your command queue a bit. If the command queue is a PriorityQueue, you could queue your normal jobs with normal priority and have an extra process queue a 'STOP' token with higher priority, once your event signals.
STOP = None
def _execute(self):
while 1:
nextCommand = self._commandQueue.get()[1]
if nextCommand is STOP:
break
self._commandExecutor.execute(nextCommand)
self._commandQueue.task_done()
def wait_for_stop_signal(self):
self._closeEvent.wait()
self._commandQueue.put((-1, STOP))
Now you run wait_for_stop_signal in its own thread, and you have the behaviour you want (but waste one thread instead of polling, pick whats worse for your use case).