How do I send data to a running python thread?

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)

Leave a Comment