本文共 3621 字,大约阅读时间需要 12 分钟。
信号量(Semaphore)是一种高级的锁机制,它与传统的锁机制有显著的区别。信号量内部维护一个计数器,而不是像传统锁那样通过占用一块独占资源来实现同步。信号量机制允许在资源占用数量超过信号量时,阻塞等待其他线程释放资源。这使得多个线程可以同时访问相同的代码区,从而提高了资源利用率。
信号量的核心机制包括两个主要操作:acquire() 和 release()。
acquire() 方法:当调用 acquire() 时,信号量的内部计数器会减1。若计数器值为0时,当前线程会被阻塞,直到其他线程调用 release() 方法将计数器恢复为正值。
release() 方法:当调用 release() 时,信号量的内部计数器会加1。如果有其他线程正在等待,可以立即被唤醒并继续执行。
信号量的计数器不能小于0。每当线程完成任务后,都应及时释放信号量,确保其他线程能够继续使用资源。
以下是一个典型的信号量使用示例:
import threadingimport timesemaphore = threading.Semaphore(3) # 允许最多3个线程同时获取锁def func(): if semaphore.acquire(): print(threading.current_thread().name + '获取锁') time.sleep(5) semaphore.release() print(threading.current_thread().name + '释放锁')for i in range(10): t = threading.Thread(target=func) t.start()
运行结果会显示:
Event对象提供了一种简单的事件通知机制。它包含一个标志位,初始状态为false。通过调用 set() 方法可以将标志位设置为true,clear() 方法将其重置为false,is_set() 方法用于检查标志位的状态。
Event对象的关键方法是 wait(),它可以接受一个超时参数。调用 wait() 时,当前线程会被阻塞,直到事件标志位被设置为true,或者超时(如果提供了超时参数)。
import threadingimport timeevent = threading.Event()def service(): print('开启服务') event.wait() # 不带参数时,会一直阻塞直到event被设置为true print('服务开启成功')def start(): time.sleep(3) print('开始执行业务') time.sleep(3) event.set() # 将事件标志位设置为truedef conn(): while True: if not event.is_set(): print('数据库连接成功') time.sleep(1) event.set() event.wait() breakif __name__ == "__main__": t1 = threading.Thread(target=conn) t2 = threading.Thread(target=start) t3 = threading.Thread(target=service) t1.start() t2.start() t3.start() 运行结果:
Condition对象是一种更高级的锁,它允许开发者在复杂的多线程环境中实现更细粒度的控制。Condition对象内部维护一个默认的RLock锁,可以通过构造函数指定其他类型的锁。
Condition对象提供了 acquire()、release() 方法,与普通锁机制相同,但更高级的功能在于它还支持 wait()、notify() 和 notify_all() 方法。
wait() 方法:释放内部锁,并挂起当前线程,直到接收到通知或超时。
notify() 方法:唤醒一个被挂起的线程,但不会释放当前锁。
notify_all() 方法:唤醒所有被挂起的线程,同样不会释放当前锁。
以下是一个经典的生产者-消费者模式示例:
from threading import Thread, Conditionimport timeimport randomqueue = []MAX_NUM = 10condition = Condition()class ProducerThread(Thread): def run(self): nums = range(5) global queue while True: condition.acquire() if len(queue) == MAX_NUM: print("Queue full, producer is waiting") condition.wait() print("Space in queue, Consumer notified the producer") num = random.choice(nums) queue.append(num) print("Produced", num) condition.notify() condition.release() time.sleep(random.random())class ConsumerThread(Thread): def run(self): global queue while True: condition.acquire() if not queue: print("Nothing in queue, consumer is waiting") condition.wait() print("Producer added something to queue and notified the consumer") num = queue.pop(0) print("Consumed", num) condition.notify() condition.release() time.sleep(random.random())producer = ProducerThread()consumer = ConsumerThread()producer.start()consumer.start() 运行结果:
转载地址:http://hyofk.baihongyu.com/