Last active
March 13, 2023 19:27
-
-
Save matthewpoer/104a29d53fc92dcdfb38d1793e076d70 to your computer and use it in GitHub Desktop.
Queue up some sleep statements and print which ones finish in what order. Demonstrates doing so with Queues, Threads, and ThreadPoolExecutor Futures. Notice that we enqueue the "15" before the "6" but of course the sleep(6) finishes well before the sleep(15)
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
Started worker and queued sleeper 3 ... 0.00016 | |
running worker for 3 ... 0.00063 | |
Started worker and queued sleeper 9 ... 0.00069 | |
running worker for 9 ... 0.00107 | |
Started worker and queued sleeper 15 ... 0.0011 | |
running worker for 15 ... 0.00145 | |
Started worker and queued sleeper 12 ... 0.00151 | |
running worker for 12 ... 0.0018 | |
Started worker and queued sleeper 6 ... 0.00192 | |
running worker for 6 ... 0.0022 | |
completed worker for 3 ... 3.00238 | |
completed worker for 6 ... 6.00734 | |
completed worker for 9 ... 9.00644 | |
completed worker for 12 ... 12.00259 | |
completed worker for 15 ... 15.00521 |
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
from queue import Queue | |
from threading import Thread | |
import time | |
START_TIME = time.time() | |
def timer(): | |
elapsed_time = round(time.time() - START_TIME, 5) | |
return f"{elapsed_time}".rjust(10) | |
def log(message: str): | |
message = message.ljust(40) | |
message = f"{message}... {timer()}" | |
print(message) | |
with open(f"{START_TIME}.log", "a") as file: | |
file.write(f"{message}\n") | |
class MyCoolWorker(Thread): | |
def __init__(self, queue): | |
Thread.__init__(self) | |
self.queue = queue | |
def run(self): | |
wait_for_seconds = self.queue.get() | |
try: | |
log(f"running worker for {wait_for_seconds}") | |
time.sleep(int(wait_for_seconds)) | |
finally: | |
log(f"completed worker for {wait_for_seconds}") | |
self.queue.task_done() | |
def main(): | |
queue = Queue() | |
test_timers = ["3", "9", "15", "12", "6"] | |
for wait_for_seconds in test_timers: | |
worker = MyCoolWorker(queue) | |
worker.daemon = True | |
worker.start() | |
log(f"Started worker and queued sleeper {wait_for_seconds}") | |
queue.put(wait_for_seconds) | |
queue.join() # blocks progress until all workers are complete | |
if __name__ == '__main__': | |
main() |
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
Starting main() ... 1e-05 | |
Starting handler() ... 0.00035 | |
Processing for 3 ... 0.00056 | |
sleep_for 3 start ... 0.00084 | |
Processing for 9 ... 0.00087 | |
sleep_for 9 start ... 0.00123 | |
Processing for 15 ... 0.00126 | |
Processing for 12 ... 0.00163 | |
sleep_for 15 start ... 0.0016 | |
Processing for 6 ... 0.00216 | |
sleep_for 12 start ... 0.0021 | |
Ending handler() ... 0.00256 | |
sleep_for 6 start ... 0.00245 | |
Ending main() ... 0.00276 | |
sleep_for 3 complete ... 3.00501 | |
sleep_for 6 complete ... 6.00786 | |
sleep_for 9 complete ... 9.00529 | |
sleep_for 12 complete ... 12.00699 | |
sleep_for 15 complete ... 15.00432 |
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
from threading import Thread | |
import time | |
START_TIME = time.time() | |
TEST_TIMERS = ["3", "9", "15", "12", "6"] | |
def timer(): | |
elapsed_time = round(time.time() - START_TIME, 5) | |
return f"{elapsed_time}".rjust(10) | |
def log(message: str): | |
message = message.ljust(40) | |
message = f"{message}... {timer()}" | |
print(message) | |
with open(f"{START_TIME}.log", "a") as file: | |
file.write(f"{message}\n") | |
def sleep_for(seconds: int): | |
log(f"sleep_for {seconds} start") | |
time.sleep(seconds) | |
log(f"sleep_for {seconds} complete") | |
def handler(): | |
log("Starting handler()") | |
for wait_for_seconds in TEST_TIMERS: | |
log(f"Processing for {wait_for_seconds}") | |
thread = Thread(target=sleep_for, args=[int(wait_for_seconds)]) | |
thread.start() | |
log("Ending handler()") | |
return True | |
def main(): | |
log("Starting main()") | |
handler() | |
log("Ending main()") | |
return True | |
if __name__ == '__main__': | |
main() |
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
sleep_for 3 start ... 0.00269 | |
sleep_for 9 start ... 0.00295 | |
sleep_for 15 start ... 0.00309 | |
sleep_for 12 start ... 0.00331 | |
sleep_for 6 start ... 0.00357 | |
sleep_for 3 complete ... 3.00493 | |
sleep_for 6 complete ... 6.00591 | |
sleep_for 9 complete ... 9.0051 | |
sleep_for 12 complete ... 12.0043 | |
sleep_for 15 complete ... 15.0074 |
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 concurrent.futures | |
import time | |
START_TIME = time.time() | |
def log(message: str): | |
message = message.ljust(30) | |
elapsed_time = f"{round(time.time() - START_TIME, 5)}".rjust(10) | |
message = f"{message}... {elapsed_time}" | |
print(message) | |
with open(f"{START_TIME}.log", "a") as file: | |
file.write(f"{message}\n") | |
TEST_TIMERS = ["3", "9", "15", "12", "6"] | |
def sleep_for(seconds: int): | |
log(f"sleep_for {seconds} start") | |
time.sleep(seconds) | |
log(f"sleep_for {seconds} complete") | |
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: | |
future_to_sleeper_map = {} | |
for wait_for_seconds in TEST_TIMERS: | |
future = executor.submit(sleep_for, int(wait_for_seconds)) | |
future_to_sleeper_map[future] = wait_for_seconds |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment