Skip to content

Instantly share code, notes, and snippets.

@matthewpoer
Last active March 13, 2023 19:27
Show Gist options
  • Save matthewpoer/104a29d53fc92dcdfb38d1793e076d70 to your computer and use it in GitHub Desktop.
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)
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
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()
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
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()
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
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