~/problems / Coordination / Semaphore

Basics: at most k at once

easy basics ~10 min

Implement run_limited(tasks, k) -> list:

  • tasks is a list of zero-argument functions (think: downloads that each need one of k network connections).
  • Start one thread per task, all right away, but let at most k tasks run at the same time. A thread that can't run yet waits until a running task finishes.
  • Return the list of results in the same order as tasks (results[i] = tasks[i]()), once every task has finished.
run_limited([lambda: 1, lambda: 2, lambda: 3], 2)   # [1, 2, 3], never more than 2 running
run_limited([], 3)                                  # []

With 6 tasks that each take 0.1s and k = 2, the whole call takes about 0.3s: never more than 2 at once, but always 2 when there are 2 waiting.

Constraints: 1 <= k, 0 <= len(tasks) <= 50. k may be larger than the number of tasks. Don't sleep or busy-wait.

Show hint

A threading.Semaphore(k) holds k permits: each thread does with sem: around its task, so the (k+1)-th thread blocks in acquire until someone releases.

Topic: Semaphore. Counting access to N resources; producer/consumer.

0:00
Ctrl ' run · Ctrl ↵ submit
esc