I have a number of threads which wait on an event, perform some action, then wait on the event again. Another thread will trigger the event when it\'s appropriate.
I can
One solution I've used in the past is the Queue class for interthread communication. It is threadsafe and can be used to easy communication between threads when using both the multiprocessing and threading libraries. You could have the child threads waiting for something to enter the queue and then process the new entry. The Queue class also has a get() method which takes a handy blocking argument.
If you want discrete, atomic events that can be processed sequentially by each thread, then do as krs1 & bot403 suggested and use a queue. The Python Queue
class is synchronized - you do not have to worry about locking to use it.
If however your needs are simpler (the event tells you that you have data available to read, etc), you can subscribe/register your threads as observers of an object responsible for triggering the events. This object would maintain the list of observer threading.Event
objects. On a trigger, it can then call set() on all of the threading.Event
objects in the list.
You don't need an Event, and you don't need both a Lock and a Queue. All you need is a Queue.
Call queue.put
to drop a message in without waiting for it to be delivered or processed.
Call queue.get
in the worker thread to wait for a message to arrive.
import threading
import Queue
active_queues = []
class Worker(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.mailbox = Queue.Queue()
active_queues.append(self.mailbox)
def run(self):
while True:
data = self.mailbox.get()
if data == 'shutdown':
print self, 'shutting down'
return
print self, 'received a message:', data
def stop(self):
active_queues.remove(self.mailbox)
self.mailbox.put("shutdown")
self.join()
def broadcast_event(data):
for q in active_queues:
q.put(data)
t1 = Worker()
t2 = Worker()
t1.start()
t2.start()
broadcast_event("first event")
broadcast_event("second event")
broadcast_event("shutdown")
t1.stop()
t2.stop()
The messages don't have to be strings; they can be any Python object.
I'm not a python programmer but if an event can only be processed once perhaps you need to switch to a message queue with the appropriate locking so that when one thread wakes up and receives the event message it will process it and remove it from the queue so its not there if other threads wake up and look in the queue.