Martol1ni
Martol1ni

Reputation: 4702

Asking another thread to do something

I have one Thread(1) that's listening for input signals, and when it gets a signal another Thread(2) should do an action. I'm struggling with whether I should share a Queue between the two threads and put functions in it from (1) and getting them in (2) in a big while loop. Does python offer better ways of communicating functioncalls between threads?

Upvotes: 1

Views: 449

Answers (1)

unutbu
unutbu

Reputation: 879341

I would use a Queue.

If you were to use a threading.Condition, or threading.Event, I don't think there is a way to tell the worker thread that there is more than one input to be processed. The communication device they provide between threads is more like a toggle switch -- on or off, notify or waiting.

Thus, if Thread(2) were in the middle of processing a signal while Thread(1) received another signal, Thread(1) would not have a good way of telling Thread(2) that another signal had arrived. In contrast, a Queue would arrange all the ducks (signals) neatly in a row, and allow Thread(2) to process them one-by-one.

import threading
import datetime as DT
import time
import Queue
import random
import itertools

sentinel = None
def worker(queue):
    for date, count in iter(queue.get, sentinel):
        now = DT.datetime.now()
        print('{}: Signal found at {}, processed at {}'
              .format(count, date.strftime('%S.%f'), now.strftime('%S.%f')))
        time.sleep(random.random()*5)

queue = Queue.Queue()
t = threading.Thread(target=worker, args=(queue, ))
t.daemon = True
t.start()

c = 0
while True:
    if random.random() < 0.05:
        queue.put((DT.datetime.now(), c))
        c += 1
    if c >= 5:
        # Tell worker to quit
        queue.put(sentinel)
        t.join()
        break

will print something like

0: Signal found at 27.308544, processed at 27.308705
1: Signal found at 27.308585, processed at 30.379586
2: Signal found at 27.308601, processed at 35.174354
3: Signal found at 27.308607, processed at 36.649155
4: Signal found at 27.308622, processed at 37.234935

Notice the signals are all found/generated (in the main thread) around 27.3, but aren't processed (in the worker thread) until much later.

Upvotes: 1

Related Questions