Created
July 20, 2013 00:58
-
-
Save alexdong/6043369 to your computer and use it in GitHub Desktop.
Guess a random number using a home-made ThreadPool.
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 random | |
import threading | |
class ThreadPool(object): | |
def __init__(self, pool_size): | |
self.pool_size = pool_size | |
self.threads = [] | |
def wait_for_thread(self): | |
"""Wait for the next thread to become available. | |
Block until the next thread is available. | |
This works by linearly pinging each thread, trying to | |
`join()` it for 50 milli-seconds. If the `join()` timeout, | |
it will move on to the next thread in the pool. This process | |
will repeat until there is one thread frees up. """ | |
while len(self.threads) == self.pool_size: | |
for thread in self.threads: | |
# If join succeeded, we have one thread freed up. | |
# Otherwise, move on to the next one and keep waiting. | |
thread.join(0.05) # Wait for 50 msec | |
if not thread.isAlive(): | |
break | |
def start(self, func, *args, **kwargs): | |
"""Start a new thread running the specified func. | |
This blocks until at least one thread becomes available in | |
the pool. | |
It is the caller's responsibility to call `wait_for_thread` | |
to make sure the thread_pool is not full. Otherwise, an | |
assertion exception will be thrown. """ | |
assert len(self.threads) < self.pool_size | |
thread = threading.Thread(target=func, args=args, kwargs=kwargs) | |
thread.start() | |
def join_all(self): | |
""" Blocks until all threads in the pool finish. """ | |
for thread in self.threads: | |
thread.join() | |
class Guesser(object): | |
def __init__(self, thread_count, size, goal): | |
self.thread_pool = ThreadPool(thread_count) | |
self.size = size | |
self.goal = goal | |
self.result = -1 | |
def run(self, *args, **kwargs): | |
n = args[0] | |
if n == self.goal: | |
self.result = n | |
def start(self): | |
for n in range(0, self.size): | |
# Start a thread to work on a new number | |
self.thread_pool.wait_for_thread() | |
self.thread_pool.start(self.run, n) | |
if self.result != -1: | |
self.thread_pool.join_all() | |
break | |
if self.result != -1: | |
print "Drum ....\nAnd, the winner is ... \n" | |
print self.result | |
else: | |
print "Bummer. The universe just collapsed. \n" | |
if __name__ == "__main__": | |
size = 1000 | |
goal = random.randint(0, size) | |
guesser = Guesser(50, size, goal) | |
guesser.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment