What is a race condition and how do you prevent it with locks?hard
A race condition happens when two threads read-modify-write shared state without synchronisation — the result depends on scheduling order. threading.Lock() prevents this: only one thread holds it at a time. A deadlock occurs when two threads each hold a lock the other needs and both wait forever.
Classic example: Thread A reads counter (5), Thread B reads counter (5), both add 1 and write back 6 — but the correct answer is 7. Always use Lock as a context manager (with lock:) to guarantee release even on exception. RLock (reentrant lock) allows the same thread to acquire it multiple times — useful when a locked function calls another locked function in the same thread. Deadlock prevention: always acquire locks in the same order across threads, use lock.acquire(timeout=5), or prefer asyncio.Lock which avoids thread issues entirely since asyncio is single-threaded.