Skip to content
← All Python tracks

Concurrency with Threads and asyncio

Python

Run several tasks at once. Start with thread pools and locks, move on to asyncio for programs that wait on many network calls, and finish with timeouts, cancellation and clean shutdown.

This track uses Python. You can make it your practice mode to browse related content across the site.

25 exercises

31 articles

Explore freely. Sign in to keep your progress.

Your learning sequence

  1. 1 When Concurrency Helps, and Which Tool to Use Read
  2. 2 Not solved yet. Download Pages with a Thread Pool Practice · Easy
  3. 3 Futures: Getting Results and Errors Back from a Thread Pool Read
  4. 4 Not solved yet. Collect Results and Errors from a Thread Pool Practice · Easy
  5. 5 Threads, Processes and the GIL Read
  6. 6 Race Conditions and Locks Read
  7. 7 Not solved yet. Fix a Counter That Loses Updates Practice · Easy
  8. 8 Check and Update Under One Lock Read
  9. 9 Not solved yet. Build a Counter That Never Goes Over Its Limit Practice · Medium
  10. 10 Make Threads Wait Without Polling Read
  11. 11 Not solved yet. Build a Blocking Queue with a Condition Practice · Medium
  12. 12 Catch Thread Errors and Stop Threads Cleanly Read
  13. 13 Not solved yet. Bring Thread Errors Back to the Caller Practice · Medium
  14. 14 Run a Big Batch on a Thread Pool Read
  15. 15 Not solved yet. Write a Pool Map That Reports Every Failure Practice · Medium
  16. 16 asyncio from Zero: Coroutines, await and the Event Loop Read
  17. 17 Not solved yet. Download Pages at the Same Time with asyncio Practice · Easy
  18. 18 Call Async Code from Synchronous Code Read
  19. 19 Not solved yet. Write a Sync Wrapper for Async Code Practice · Easy
  20. 20 Write Type Hints for Async Code Read
  21. 21 Not solved yet. Accept Any Fetcher You Can Await Practice · Medium
  22. 22 Not solved yet. Resolve Values, Awaitables and Factories in Order Practice · Medium
  23. 23 Stream Paged Results with Async Generators Read
  24. 24 Not solved yet. Build a Paginator You Can Close Early Practice · Medium
  25. 25 Keep Track of Background Tasks Read
  26. 26 Not solved yet. Build an Owner for Background Tasks Practice · Medium
  27. 27 Run Related Tasks Together with TaskGroup Read
  28. 28 Not solved yet. Fetch Many Pages with a TaskGroup Practice · Medium
  29. 29 Cancel a Task and Clean Up After It Read
  30. 30 Not solved yet. Run Async Cleanup Without Hiding the Real Error Practice · Hard
  31. 31 Keep yield Outside Timeouts and TaskGroups Read
  32. 32 Not solved yet. Batch an Async Stream and Close Its Source Practice · Hard
  33. 33 Release Async Resources with contextlib Read
  34. 34 Not solved yet. Release a Connection However the Stream Ends Practice · Hard
  35. 35 Set Timeouts and Share One Deadline Read
  36. 36 Not solved yet. Retry Within One Shared Deadline Practice · Medium
  37. 37 Write Async Context Managers That Clean Up Read
  38. 38 Feed Workers Through a Bounded Queue Read
  39. 39 Not solved yet. Process a Stream with a Bounded Queue Practice · Medium
  40. 40 Run Blocking Calls from Async Code Read
  41. 41 Not solved yet. Build a Typed Async Wrapper for Blocking Calls Practice · Medium
  42. 42 Shut Down an asyncio Service Gracefully Read
  43. 43 Not solved yet. Build a Service That Shuts Down in Stages Practice · Hard
  44. 44 Debug a Slow or Stuck Async Service Read
  45. 45 Carry a Request ID Across Tasks with contextvars Read
  46. 46 Not solved yet. Build a Request ID That Follows Tasks and Threads Practice · Medium
  47. 47 Start Tasks Right Away with Eager Tasks Read
  48. 48 Limit Concurrency, Request Rate and Queued Work Read
  49. 49 Not solved yet. Map Over a Stream with at Most N Calls at Once Practice · Hard
  50. 50 Choose Between asyncio, AnyIO and Trio Read
  51. 51 Fix Disagreements Between mypy and Pyright Read
  52. 52 Choose the Right Concurrency Tool for Each Job Read
  53. 53 Write Concurrency Tests with Events, Not Sleeps Read
  54. 54 Make Async Tests Repeatable with Handshakes and Fake Clocks Read
  55. 55 Not solved yet. Find Leaked Tasks and Start Threads Together Practice · Medium
  56. 56 Not solved yet. Capstone: Build an Async Worker Pool with Retries and Clean Shutdown Practice · Hard

Check yourself

6 questions · not saved while you're signed out

Use these questions to check your understanding and compare explanations. Your score does not affect track completion.

0 / 6 correct

One thread acquires each lock twice, the second time with blocking=False. What does that second call return for Lock and for RLock?

Choose one answer to reveal the explanations. Answers are kept only while this page is open.

from threading import Lock, RLock

lock = Lock()
first = lock.acquire()
second = lock.acquire(blocking=False)
print(first, second)
lock.release()

rlock = RLock()
first = rlock.acquire()
second = rlock.acquire(blocking=False)
print(first, second)
rlock.release()
rlock.release()
Question 1 of 6