Last active
August 29, 2015 14:24
-
-
Save jg75/bd6941a98f6a515c2569 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 threading, os, logging | |
from math import sqrt | |
class threadsafe_iterator: | |
def __init__(self, iterator): | |
self.iterator = iterator | |
self.lock = threading.Lock() | |
def __iter__(self): | |
return self | |
def next(self): | |
with self.lock: | |
return self.iterator.next() | |
def threadsafe_generator(function): | |
def inner(*args, **kwargs): | |
return threadsafe_iterator(*args, **kwargs) | |
return function | |
def process_logger(): | |
def _logger(function): | |
def inner(*args, **kwargs): | |
identifier = "%s:%s" % (str(os.getpid()), str(args[0])) | |
logdir = os.path.join(os.getcwd(), 'logs') | |
logfile = os.path.join(logdir, 'blah-' + identifier + '.log') | |
logger = logging.getLogger(identifier) | |
file_handle = logging.FileHandler(logfile) | |
logger.addHandler(file_handle) | |
return function(*args, **kwargs) | |
return inner | |
return _logger | |
@threadsafe_generator | |
def counter(): | |
i = 0 | |
while True: | |
i += 1 | |
yield i | |
def gen_primes(count): | |
""" | |
Generate n prime numbers | |
""" | |
primes = [2] | |
while len(primes) < count: | |
num = primes[-1] | |
while True: | |
num += 1 | |
if num % 2: | |
for n in range(3, int(sqrt(num)+1), 2): | |
if not num % n: | |
break | |
else: | |
primes.append(num) | |
break | |
return primes | |
@process_logger() | |
def worker(number): | |
""" | |
Worker generates the n-thousandth prime number | |
""" | |
pid = str(os.getpid()) | |
logger = logging.getLogger(pid) | |
child_logger = logging.getLogger("%s:%s" % (pid, str(number))) | |
primes = gen_primes(number * 1000) | |
child_logger.info(primes) | |
logger.info(primes[-1]) | |
def start_workers(workers): | |
""" | |
Spawn up to n workers until all work is complete | |
""" | |
children = [] | |
number = counter() | |
next_number = 0 | |
logdir = os.path.join(os.getcwd(), 'logs') | |
logfile = "blah.log" | |
if workers < 1: | |
return | |
if not os.path.exists(logdir): | |
os.makedirs(logdir) | |
logging.basicConfig(filename=os.path.join(logdir, logfile), level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
while next_number < 100: | |
while len(children) < workers: | |
next_number = number.next() | |
pid = os.fork() | |
if not pid: | |
worker(next_number) | |
os._exit(0) | |
else: | |
children.append(pid) | |
logger.info("Started: %d" % pid) | |
child = os.wait()[0] | |
children.remove(child) | |
logger.info("Stopped: %d" % child) | |
if __name__ == '__main__': | |
start_workers(10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment