Python 锁
最后修改:2025 年 2 月 15 日
在本文中,我们将展示如何使用 threading.Lock 同步 Python 线程。
Lock 是一种同步原语,可确保一次只有一个线程可以访问共享资源。它对于防止多个线程尝试同时修改共享数据时出现的竞态条件非常有用。
Lock 有两种状态:锁定和未锁定。线程可以使用 acquire 方法获取锁,并使用 release 方法释放锁。如果锁已被另一个线程获取,则调用线程将阻塞,直到锁被释放。
锁示例
以下示例演示了如何使用 threading.Lock 来保护共享资源。
import threading
class SharedResource:
def __init__(self):
self.lock = threading.Lock()
self.value = 0
def increment(self):
with self.lock: # Acquire and release the lock automatically
self.value += 1
print(f"Value after increment: {self.value}")
def worker(shared_resource):
for _ in range(5): # Each thread increments the value 5 times
shared_resource.increment()
def main():
shared_resource = SharedResource()
threads = []
for i in range(3): # Create 3 threads
thread = threading.Thread(target=worker, args=(shared_resource,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join() # Wait for all threads to complete
print(f"Final value: {shared_resource.value}")
if __name__ == "__main__":
main()
在此程序中,使用 Lock 来保护共享的整数值。多个线程递增该值,并且锁确保一次只有一个线程可以修改该值。
self.lock = threading.Lock()
SharedResource 类使用 Lock 初始化,以保护共享值。
with self.lock: # Acquire and release the lock automatically
with 语句用于自动获取和释放锁,从而确保适当的同步。
shared_resource = SharedResource()
初始化 SharedResource,并使用锁来保护共享值。
$ python main.py Value after increment: 1 Value after increment: 2 Value after increment: 3 Value after increment: 4 Value after increment: 5 Value after increment: 6 Value after increment: 7 Value after increment: 8 Value after increment: 9 Value after increment: 10 Value after increment: 11 Value after increment: 12 Value after increment: 13 Value after increment: 14 Value after increment: 15 Final value: 15
带超时的锁
以下示例演示了如何使用带超时的 Lock。如果线程无法在指定的超时时间内获取锁,它将继续执行而不修改共享资源。
import threading
import time
class SharedResource:
def __init__(self):
self.lock = threading.Lock()
self.value = 0
def increment(self):
if self.lock.acquire(timeout=1): # Try to acquire the lock with a timeout
try:
self.value += 1
print(f"Value after increment: {self.value}")
finally:
self.lock.release() # Release the lock
else:
print("Could not acquire the lock")
def worker(shared_resource):
for _ in range(5): # Each thread increments the value 5 times
shared_resource.increment()
time.sleep(0.5) # Simulate some work
def main():
shared_resource = SharedResource()
threads = []
for i in range(3): # Create 3 threads
thread = threading.Thread(target=worker, args=(shared_resource,))
threads.append(thread)
thread.start()
for thread in threads:
thread.join() # Wait for all threads to complete
print(f"Final value: {shared_resource.value}")
if __name__ == "__main__":
main()
在此程序中,Lock 与超时一起使用。如果线程无法在 1 秒内获取锁,它将继续执行而不修改共享资源。
if self.lock.acquire(timeout=1): # Try to acquire the lock with a timeout
acquire 方法被调用,超时时间为 1 秒。如果在此时间内未获取锁,则线程将继续执行而不修改共享资源。
$ python main.py Value after increment: 1 Value after increment: 2 Value after increment: 3 Value after increment: 4 Value after increment: 5 Value after increment: 6 Value after increment: 7 Value after increment: 8 Value after increment: 9 Value after increment: 10 Value after increment: 11 Value after increment: 12 Value after increment: 13 Value after increment: 14 Value after increment: 15 Final value: 15
带锁的线程安全队列示例
以下示例演示了如何使用 threading.Lock 来实现线程安全队列。锁确保一次只有一个线程可以修改队列。
import threading
import time
import queue
class ThreadSafeQueue:
def __init__(self):
self.queue = queue.Queue()
self.lock = threading.Lock()
def put(self, item):
with self.lock: # Acquire and release the lock automatically
self.queue.put(item)
print(f"Added item: {item}")
def get(self):
with self.lock: # Acquire and release the lock automatically
if not self.queue.empty():
item = self.queue.get()
print(f"Removed item: {item}")
return item
return None
def producer(safe_queue):
for i in range(5): # Produce 5 items
safe_queue.put(i)
time.sleep(0.5) # Simulate production time
def consumer(safe_queue):
for _ in range(5): # Consume 5 items
safe_queue.get()
time.sleep(1) # Simulate consumption time
def main():
safe_queue = ThreadSafeQueue()
# Create producer and consumer threads
producer_thread = threading.Thread(target=producer, args=(safe_queue,))
consumer_thread = threading.Thread(target=consumer, args=(safe_queue,))
producer_thread.start()
consumer_thread.start()
producer_thread.join()
consumer_thread.join()
print("Queue operations completed")
if __name__ == "__main__":
main()
在此程序中,使用 Lock 来保护共享队列。生产者线程将项目添加到队列,而消费者线程从队列中删除项目。锁确保一次只有一个线程可以修改队列。
self.lock = threading.Lock()
ThreadSafeQueue 类使用 Lock 初始化,以保护共享队列。
with self.lock: # Acquire and release the lock automatically
with 语句用于自动获取和释放锁,从而确保适当的同步。
safe_queue = ThreadSafeQueue()
初始化 ThreadSafeQueue,并使用锁来保护共享队列。
$ python main.py Added item: 0 Removed item: 0 Added item: 1 Added item: 2 Removed item: 1 Added item: 3 Added item: 4 Removed item: 2 Removed item: 3 Removed item: 4 Queue operations completed
来源
在本文中,我们展示了如何使用 Lock 同步 Python 线程以进行资源管理。
作者
列出所有 Python 教程。