This code is pretty hopeless - give up on it and do something sane ;-) What's sane? Use a Queue.Queue
. That's designed to do what you want.
Replace:
self.event = Event()
self.taskInfos = []
with:
self.taskInfos = Queue.Queue()
(of course you have to import Queue
too).
To add a task:
self.taskInfos.put((msg, task))
To get a task:
msg, task = self.taskInfos.get()
That will block until a task is available. There are also options to do a non-blocking .get()
attempt, and to do a .get()
attempt with a timeout (read the docs).
Trying to fix the code you have would be a nightmare. At heart, Event
s are not powerful enough to do what you need for thread safety in this context. In fact, any time you see code doing Event.clear()
, it's probably buggy (subject to races).
Edit: what will go wrong next
If you continue trying to fix this code, this is likely to happen next:
the queue is empty
thread 1 does len(self.taskInfo) == 0, and loses its timeslice
thread 2 does self.taskInfos.append((msg, task))
and does self.event.set()
and loses its timeslice
thread 1 resumes and does self.event.clear()
and does self.event.wait()
Oops! Now thread 1 waits forever, despite that a task is on the queue.
That's why Python supplies Queue.Queue
. You're exceedingly unlikely to get a correct solution using a feeble Event
.