How to Use Thread Lock in Python for Safe Threading
In Python, use
threading.Lock() to create a lock object that prevents multiple threads from accessing shared resources simultaneously. Acquire the lock with lock.acquire() before the critical section and release it with lock.release() after to ensure thread safety.Syntax
The basic syntax involves creating a lock object and using acquire() and release() methods to control access.
lock = threading.Lock(): Creates a new lock.lock.acquire(): Blocks the thread until the lock is available.lock.release(): Releases the lock so other threads can acquire it.
python
import threading lock = threading.Lock() # Acquire the lock lock.acquire() try: # Critical section: code that accesses shared resources pass finally: # Always release the lock lock.release()
Example
This example shows two threads incrementing a shared counter safely using a thread lock to avoid race conditions.
python
import threading counter = 0 lock = threading.Lock() def increment(): global counter for _ in range(100000): lock.acquire() try: counter += 1 finally: lock.release() thread1 = threading.Thread(target=increment) thread2 = threading.Thread(target=increment) thread1.start() thread2.start() thread1.join() thread2.join() print(f"Final counter value: {counter}")
Output
Final counter value: 200000
Common Pitfalls
Common mistakes include forgetting to release the lock, which can cause deadlocks, or not using locks at all, leading to race conditions.
Always use try...finally to ensure the lock is released even if an error occurs.
python
import threading lock = threading.Lock() # Wrong way: forgetting to release lock lock.acquire() # Critical section # lock.release() # Oops, missing release causes deadlock # Right way: lock.acquire() try: # Critical section pass finally: lock.release()
Quick Reference
| Method | Description |
|---|---|
| threading.Lock() | Creates a new lock object |
| lock.acquire() | Blocks until the lock is available and acquires it |
| lock.release() | Releases the lock for other threads |
| with lock: | Context manager to acquire and release lock automatically |
Key Takeaways
Use threading.Lock() to create a lock for controlling thread access.
Always acquire the lock before accessing shared data and release it afterward.
Use try...finally or with statement to ensure the lock is released properly.
Forgetting to release a lock causes deadlocks and freezes your program.
Locks prevent race conditions by allowing only one thread in the critical section.