nextRound
TechnologiesCoding ProblemsBookmarksLearning PathsLogin
nextRound
TechnologiesCoding ProblemsBookmarksLearning PathsLogin
Questions
3 of 9
1How does Python's asyncio event loop achieve concurrency without using multiple threads?
2What is the difference between threading, multiprocessing, and asyncio, and when would you choose each?
3What causes a deadlock in multithreaded code, and how can it be avoided?
4Why does multiprocessing avoid the GIL problem, and what overhead does it introduce instead?
5Given the GIL, why can multithreading still improve performance for I/O-bound tasks but not CPU-bound tasks?
6What is the difference between async def and a regular function, and what does await actually do?
7How would you run CPU-bound work alongside an asyncio application without blocking the event loop?
8What is a race condition, and how would you prevent one using threading.Lock?
9What is the Global Interpreter Lock (GIL), and why does it exist in CPython?
PythonPython
Basics
Control Flow and Functions
Data Structures
Comprehensions & Functional Programming
Iterators, Generators & Decorators
Object-Oriented Programming
Exception Handling & Debugging
Concurrency & Parallelism
Performance & Optimization
Testing
Security
Modules, Packaging & Environment
Type Hinting & Modern Python
System Design & Architecture with Python
Best Practices & Design Patterns
Edge Cases & Tricky Interview Questions
03 / 09
nextRound

AI-powered interview preparation platform. Practice with curated questions, mock interviews, and personalized learning paths to crack your dream tech interview.

Quick Links

  • Technologies
  • Mock Interviews
  • Saved Questions
  • Pricing

Company

  • About Us
  • Contact Us

Legal

  • Privacy Policy
  • Terms of Use

© 2026 nextRound. All rights reserved.

What causes a deadlock in multithreaded code, and how can it be avoided?

Difficulty: 9/10
Deadlock, Locks, Debugging, Threading

Deadlock comes from circular lock dependencies; break the cycle with ordering or timeouts

A deadlock needs four conditions: mutual exclusion, hold-and-wait, no preemption, and circular wait. The most common Python case is two threads acquiring two locks in opposite orders, or a thread acquiring a non-reentrant Lock twice. The standard fixes are: establish a global lock ordering and always acquire locks in that order, use a single lock instead of two when possible, use a timeout on acquire so the cycle is broken and the code can retry or fail, and prefer higher-level primitives such as queue.Queue or an executor that manage coordination internally. For debugging, faulthandler.dump_traceback_later prints all thread stacks after a timeout, which is usually enough to see the two threads waiting on each other.

  1. 1

    Global lock ordering: assign each lock a rank and always acquire in ascending order.

  2. 2

    Timeout: lock.acquire(timeout=5) avoids hanging forever; pair it with a clear error or retry policy.

  3. 3

    Single lock or a higher-level primitive removes the cycle entirely.

  4. 4

    Detect with faulthandler.dump_traceback_later(timeout=10) or by sending SIGABRT after enabling faulthandler.

  5. 5

    Trade-off: coarse locks reduce deadlock risk but reduce concurrency. Fine-grained locks increase throughput but multiply ordering hazards.

  6. 6

    Common mistake: acquiring a lock inside a callback or signal handler, which can reenter and deadlock.

  7. 7

    Common mistake: holding a lock across a blocking IO call, which turns a latency problem into a deadlock under load.

  8. 8

    Version note: faulthandler has been in the stdlib since 3.3. Lock.acquire accepts a timeout in all Python 3 versions.

Scenario Questions

0-2 years experience

  1. 1Two threads each hold one lock and wait for the other. What is this called?
  2. 2What does lock.acquire(timeout=1) return if it fails?

2-5 years experience

  1. 1Your service hangs and CPU is idle. How do you get a stack trace of every thread?
  2. 2A function locks the same non-reentrant lock twice and hangs. What is the fix?

5-8 years experience

  1. 1You have dozens of locks in a codebase. How do you introduce and enforce a global ordering?
  2. 2You need to avoid holding a lock during IO without introducing a race. How do you restructure the critical section?

8+ years experience

  1. 1Design a component that coordinates multiple resources with no circular waits, including a documented lock hierarchy and detection for violations.
  2. 2Explain how deadlock can arise between threads, processes, and async tasks, and how to build a diagnostic that pinpoints the cycle in production.

Follow-up Questions

  • How does an RLock change the deadlock analysis for reentrant code?
  • What is a livelock and how does it differ from a deadlock?
Sharethis question

Share via WhatsApp, X, Facebook, LinkedIn or copy link. Open Graph preview enabled.