PythiloLesson 1 of 12 · progress kept in this browser

Threads and join

Most programs spend their time waiting: for a disk, a network, a database. Concurrency lets those waits overlap, so three downloads that each wait a second can finish in about one second instead of three.

Computing is different. In the standard build of Python, a global interpreter lock, the GIL, lets only one thread run Python code at a time. A thread that sleeps or waits for I/O releases it, so threads speed up waiting, not arithmetic.

import threading
import time

results = {}

def download(name):
    time.sleep(0.01)  # waiting for I/O
    results[name] = len(name)

threads = [
    threading.Thread(target=download,
                     args=(name,))
    for name in ["a.txt", "notes.md"]
]
for t in threads:
    t.start()
for t in threads:
    t.join()
print(sorted(results.items()))

start() launches a thread and returns at once. join() waits until it finishes. Start them all, then join them all: joining right after each start runs them one at a time.

A thread cannot hand back a return value, so its function stores the result somewhere you read after join().

Your task

Write run_all(jobs), where jobs is a list of functions that take no arguments. Run every job in its own thread, all at the same time, wait for all of them, and return their results as a list in the order of jobs.

This lesson uses threads, which Python in this browser does not include. Read it here, and run and check it in the Pythilo app on iPhone or iPad.