In [12]:
import threading

In [13]:
def printNum(x):
    print x

In [16]:
for i in xrange(20):
    thread = threading.Thread(target=printNum, args=(i,))
    thread.start()


0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

In [17]:
import logging
import random
import threading
import time

In [18]:
logging.basicConfig(level=logging.DEBUG,
                    format='(%(threadName)-10s) %(message)s',
                    )

In [19]:
class Counter(object):
    def __init__(self, start=0):
        self.lock = threading.Lock()
        self.value = start
    def increment(self):
        logging.debug('Waiting for lock')
        self.lock.acquire()
        try:
            logging.debug('Acquired lock')
            self.value = self.value + 1
        finally:
            self.lock.release()

In [20]:
def worker(c):
    for i in range(2):
        pause = random.random()
        logging.debug('Sleeping %0.02f', pause)
        time.sleep(pause)
        c.increment()
    logging.debug('Done')

In [21]:
counter = Counter()
for i in range(2):
    t = threading.Thread(target=worker, args=(counter,))
    t.start()

In [ ]:
logging.debug('Waiting for worker threads')
main_thread = threading.currentThread()
for t in threading.enumerate():
    if t is not main_thread:
        t.join()
logging.debug('Counter: %d', counter.value)