Created
October 31, 2016 19:34
-
-
Save matklad/f5f076bc24a474a0e5bdb78fc1011013 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 heapq | |
import random | |
import time | |
from threading import Thread | |
def alarm(span, count): | |
for _ in range(count): | |
time.sleep(span) | |
print(span) | |
def make_tasks(n, span, count): | |
result = [] | |
for _ in range(n): | |
s = random.randrange(span) | |
result.append((s, count)) | |
return result | |
########### | |
# Threads # | |
########### | |
def thread_execute(tasks): | |
for task in tasks: | |
Thread(target=alarm, args=task).start() | |
################## | |
# State machines # | |
################## | |
class AlarmTask: | |
def __init__(self, span, count): | |
self.left = count | |
self.span = span | |
self.started = False | |
def next(self): | |
if self.left == 0: | |
return ("Stop", None) | |
if self.started: | |
print(self.span) | |
self.left -= 1 | |
self.started = True | |
return ("Sleep", self.span) | |
def run_to_completion(tasks): | |
work = [(0, i, t) for (i, t) in enumerate(tasks)] | |
heapq.heapify(work) | |
while work: | |
t = time.time() | |
(wakeup, id, a) = heapq.heappop(work) | |
to_sleep = wakeup - t | |
if to_sleep > 0: | |
time.sleep(to_sleep) | |
(cmd, span) = a.next() | |
if cmd == "Sleep": | |
wakeup = time.time() + span | |
heapq.heappush(work, (wakeup, id, a)) | |
def fsm_execute(tasks): | |
run_to_completion([AlarmTask(*t) for t in tasks]) | |
############## | |
# Generators # | |
############## | |
def task(f): | |
class T: | |
def __init__(self, *args): | |
self.g = f(*args) | |
def next(self): | |
try: | |
return next(self.g) | |
except StopIteration: | |
return ("Stop", None) | |
return T | |
@task | |
def async_alarm(span, count): | |
for _ in range(count): | |
yield ("Sleep", span) | |
print(span) | |
def async_execute(tasks): | |
run_to_completion([async_alarm(*t) for t in tasks]) | |
# tasks = make_tasks(10, 10, 3) | |
tasks = make_tasks(10**4, 10**4, 3) | |
# thread_execute(tasks) | |
# fsm_execute(tasks) | |
async_execute(tasks) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment