Last active
November 21, 2016 00:16
-
-
Save tonyslowdown/f56d4843ab0fed430bea260e7cc5347f to your computer and use it in GitHub Desktop.
Examples of threading in python taken from slides (http://www.dabeaz.com/usenix2009/concurrent/Concurrent.pdf) that @dabeaz presented at USENIX Technical Conference, June 15, 2009 and other resources
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import time | |
import threading | |
""" | |
Threads defined by a class | |
""" | |
class CountdownThread(threading.Thread): | |
def __init__(self,count): | |
threading.Thread.__init__(self) | |
self.count = count | |
def run(self): | |
while self.count > 0: | |
print "Counting down", self.count | |
self.count -= 1 | |
time.sleep(5) | |
return | |
t1 = CountdownThread(10) # Create the thread object | |
t1.start() # Launch the thread | |
t2 = CountdownThread(20) # Create another thread | |
t2.start() # Launch | |
""" | |
Threads defined by a function | |
""" | |
def countdown(count): | |
while count > 0: | |
print "Counting down", count | |
count -= 1 | |
time.sleep(5) | |
t1 = threading.Thread(target=countdown,args=(10,)) | |
t1.start() | |
""" | |
Joining a thread | |
""" | |
t.start() # Launch a thread | |
... | |
# Do other work | |
... | |
# Wait for thread to finish | |
t.join() # Waits for thread t to exit | |
""" | |
Daemonic threads | |
""" | |
t.daemon = True | |
t.setDaemon(True) | |
""" | |
Mutex | |
""" | |
x = 0 | |
x_lock = threading.Lock() | |
# Critical section | |
with x_lock: | |
# statements using x | |
pass | |
""" | |
Nested locks will cause mysterious deadlocks | |
""" | |
x = 0 | |
y = 0 | |
x_lock = threading.Lock() | |
y_lock = threading.Lock() | |
with x_lock: | |
statements using x | |
... | |
with y_lock: | |
statements using x and y | |
... | |
""" | |
Rlock: Reentrant Mutex Lock | |
http://effbot.org/zone/thread-synchronization.htm | |
http://stackoverflow.com/questions/22885775/what-is-the-difference-between-lock-and-rlock | |
""" | |
m = threading.RLock() # Create a lock | |
m.acquire() # Acquire the lock | |
m.release() # Release the lock | |
class Foo(object): | |
lock = threading.RLock() | |
def bar(self): | |
with Foo.lock: | |
... | |
def spam(self): | |
with Foo.lock: | |
... | |
self.bar() # Calling other methods holding the lock | |
... | |
""" | |
Semaphores | |
""" | |
m = threading.Semaphore(n) # Create a semaphore | |
m.acquire() # Waits if the count is 0, otherwise decrements the count and continues | |
m.release() # Increments the count and signals waiting threads (if any) | |
# Example | |
sema = threading.Semaphore(5) # Max: 5-threads running function simulaneously | |
def fetch_page(url): | |
sema.acquire() | |
try: | |
u = urllib.urlopen(url) | |
return u.read() | |
finally: | |
sema.release() | |
# Regular Semaphore can increment its counter by calling release() many times | |
# BoundedSemaphore - raises ValueError if release() is called more than acquire() | |
# Use BoundedSemaphore to avoid programming erros | |
semaphore = threading.BoundedSemaphore() | |
semaphore.acquire() # decrements the counter | |
... access the shared resource | |
semaphore.release() # increments the counter | |
""" | |
Events | |
""" | |
e = threading.Event() | |
e.isSet() # Return True if event set | |
e.set() # Set event | |
e.clear() # Clear event | |
e.wait() # Wait for event | |
# Example | |
init = threading.Event() | |
def worker(): | |
init.wait() # Wait until initialized | |
statements | |
... | |
def initialize(): | |
statements # Setting up | |
statements # ... | |
... | |
init.set() # Done initializing | |
Thread(target=worker).start() # Launch workers | |
Thread(target=worker).start() | |
Thread(target=worker).start() | |
initialize() # Initialize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment