You can use a Queue.Queue
(or queue.Queue
in Python 3) for this:
import threading
import time
from Queue import Queue
print_lock = threading.Lock()
class MyThread(threading.Thread):
def __init__(self, queue, args=(), kwargs=None):
threading.Thread.__init__(self, args=(), kwargs=None)
self.queue = queue
self.daemon = True
self.receive_messages = args[0]
def run(self):
print threading.currentThread().getName(), self.receive_messages
val = self.queue.get()
self.do_thing_with_message(val)
def do_thing_with_message(self, message):
if self.receive_messages:
with print_lock:
print threading.currentThread().getName(), "Received {}".format(message)
if __name__ == '__main__':
threads = []
for t in range(10):
q = Queue()
threads.append(MyThread(q, args=(t % 2 == 0,)))
threads[t].start()
time.sleep(0.1)
for t in threads:
t.queue.put("Print this!")
for t in threads:
t.join()
We pass a Queue
instance to each thread, and send our message to the Thread
using queue.put
. We wait for the message to arrive in the run
method, which is the part of the Thread
object that’s actually running in a separate thread of execution. Once we get the message, we call do_thing_with_message
, which will run in the same background thread.
I’ve also added a threading.Lock
to the code so the prints to stdout don’t get mixed up.
Edit:
If you want to be able to deliver multiple messages to the thread, just use a loop:
def run(self):
print threading.currentThread().getName(), self.receive_messages
while True:
val = self.queue.get()
if val is None: # If you send `None`, the thread will exit.
return
self.do_thing_with_message(val)