博客
关于我
Python 中Semaphore 信号量对象、Event事件、Condition
阅读量:799 次
发布时间:2023-03-06

本文共 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()

    运行结果会显示:

    • Thread-1 获取锁
    • Thread-2 获取锁
    • Thread-3 获取锁
    • Thread-3 释放锁
    • Thread-2 释放锁
    • Thread-4 获取锁
    • Thread-5 获取锁
    • Thread-1 释放锁
    • Thread-6 获取锁
    • Thread-6 释放锁
    • Thread-7 获取锁
    • Thread-4 释放锁
    • Thread-8 获取锁
    • Thread-5 释放锁
    • Thread-9 获取锁
    • Thread-8 释放锁
    • Thread-10 获取锁
    • Thread-7 释放锁
    • Thread-9 释放锁
    • Thread-10 释放锁

    Event事件对象

    Event对象提供了一种简单的事件通知机制。它包含一个标志位,初始状态为false。通过调用 set() 方法可以将标志位设置为trueclear() 方法将其重置为falseis_set() 方法用于检查标志位的状态。

    Event对象的关键方法是 wait(),它可以接受一个超时参数。调用 wait() 时,当前线程会被阻塞,直到事件标志位被设置为true,或者超时(如果提供了超时参数)。

    示例:Event的实际应用

    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对象是一种更高级的锁,它允许开发者在复杂的多线程环境中实现更细粒度的控制。Condition对象内部维护一个默认的RLock锁,可以通过构造函数指定其他类型的锁。

    Condition对象提供了 acquire()release() 方法,与普通锁机制相同,但更高级的功能在于它还支持 wait()notify()notify_all() 方法。

  • wait() 方法:释放内部锁,并挂起当前线程,直到接收到通知或超时。

  • notify() 方法:唤醒一个被挂起的线程,但不会释放当前锁。

  • notify_all() 方法:唤醒所有被挂起的线程,同样不会释放当前锁。

  • 示例:Condition的实际应用

    以下是一个经典的生产者-消费者模式示例:

    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()

    运行结果:

    • ProducerThread: Produced 2
    • ConsumerThread: Consumed 2
    • ProducerThread: Produced 3
    • ConsumerThread: Consumed 3
    • ...(结果会根据随机数生成,展示部分输出示例)

    转载地址:http://hyofk.baihongyu.com/

    你可能感兴趣的文章
    Python Selenium - 获取href值
    查看>>
    Python Selenium实现自动化测试及Chrome驱动使用!
    查看>>
    Python Selenium搭建UI自动化测试框架
    查看>>
    Python Selenium模块详解
    查看>>
    Python selenium爬取影评生成词云图
    查看>>
    python selenium自动化测试报告
    查看>>
    Python selenium自动化测试框架实战 —— 登录测试案例
    查看>>
    Python Selenium设计模式 —— POM
    查看>>
    Python Serial:如何使用 read 或 readline 函数一次读取多个字符
    查看>>
    Python set([]) 如何检查两个对象是否相等?一个对象需要定义哪些方法来自定义它?
    查看>>
    Python setup.py:数据文件无法复制目录:不存在或不是常规文件
    查看>>
    Python setuptools sdist:仅安装版本化文件
    查看>>
    Python Shell下使用matplotlib
    查看>>
    Python Slice How-to,我知道Python Slice,但我怎么才能使用内置的Slice对象呢?
    查看>>
    python socket分包发送数据
    查看>>
    python socket模块_Python socket模块实现TCP服务端客户端
    查看>>
    Python SOCKS5代理客户端HTTPS
    查看>>
    Python Soc网络分析:通过使用函数迭代列表来计算机会网络
    查看>>
    Python SQL和NoSQL数据库操作实战
    查看>>
    python stdout flush_sys.stdout.flush()方法的用法
    查看>>