28

I'm reading Python 3's Threading documentation but I'm having trouble understanding the material.

I've gotten two timers to run side by side but I don't know how to make these two threads interact with each other. Lock, pass an event or anything.

Could somebody just dump a simple full example here with brief description of what it does?

I'm trying to learn 3.3 so if possible would you be able to post code that works for this version. I'm also finding that the tutorials I find aren't letting me know what version of Python they're exampling.

martineau
  • 119,623
  • 25
  • 170
  • 301
Tolure
  • 859
  • 1
  • 14
  • 34
  • Define "interact". There's multiple ways threads can communicate with each other, each for different purposes (e.g. passing data, synchronizing resource access, etc). – l4mpi Apr 24 '13 at 18:56
  • Any type. Just a few examples so that I can start rapping my head around it. Seeing the structure and reading simple codes of others help me 10 fold in understanding a new language. – Tolure Apr 25 '13 at 06:15
  • 1
    [multiple producers/consumers example for gevent, threading, multiprocessing](http://stackoverflow.com/a/9252020/4279) – jfs Apr 25 '13 at 21:24
  • [simple `multiprocessing.Pool` example](http://stackoverflow.com/a/14594205/4279) – jfs Apr 25 '13 at 21:25

1 Answers1

64

Example based on queue documentation:

#!python3
import threading
from queue import Queue
import time

# lock to serialize console output
lock = threading.Lock()

def do_work(item):
    time.sleep(.1) # pretend to do some lengthy work.
    # Make sure the whole print completes or threads can mix up output in one line.
    with lock:
        print(threading.current_thread().name,item)

# The worker thread pulls an item from the queue and processes it
def worker():
    while True:
        item = q.get()
        do_work(item)
        q.task_done()

# Create the queue and thread pool.
q = Queue()
for i in range(4):
     t = threading.Thread(target=worker)
     t.daemon = True  # thread dies when main thread (only non-daemon thread) exits.
     t.start()

# stuff work items on the queue (in this case, just a number).
start = time.perf_counter()
for item in range(20):
    q.put(item)

q.join()       # block until all tasks are done

# "Work" took .1 seconds per task.
# 20 tasks serially would be 2 seconds.
# With 4 threads should be about .5 seconds (contrived because non-CPU intensive "work")
print('time:',time.perf_counter() - start)

Output:

Thread-3 2
Thread-1 0
Thread-2 1
Thread-4 3
Thread-3 4
Thread-1 5
Thread-2 6
Thread-4 7
Thread-3 8
Thread-1 9
Thread-2 10
Thread-4 11
Thread-3 12
Thread-1 13
Thread-2 14
Thread-4 15
Thread-1 17
Thread-3 16
Thread-2 18
Thread-4 19
time: 0.5017914706686906
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • 3
    @Tolure: here's a [`concurrent.futures`](http://docs.python.org/3.3/library/concurrent.futures.html) analog that [does similar thing](http://ideone.com/M6zPeR). – jfs Apr 25 '13 at 20:51
  • The lines: `def worker(): while True: item = q.get() do_work(item) q.task_done()` I am trying to understand how this `while True` loop will be break – Eduardo Reis May 22 '16 at 16:50
  • Never mind, I just found this answer explaining it: http://stackoverflow.com/a/7106193/2313889 – Eduardo Reis May 22 '16 at 17:40