在python中的基本同步原语

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
云原生网关 MSE Higress,422元/月
应用实时监控服务ARMS - 应用监控,每月50GB免费额度
简介: 【6月更文挑战第23天】本文介绍了Python `asyncio`库中的同步原语,包括Lock、Event、Condition、Semaphore和BoundedSemaphore,以及Queue和PriorityQueue。`asyncio` API设计与`threading`模块相似,

简介

在python中asyncio包的Lock提供基本的锁定机制,
Event支持异步事件等待,
Condition允许条件等待,
Semaphore管理资源计数,
BoundedSemaphore限制在一定范围内。
所有这些原语非线程安全,适用于协程间的同步。
队列Queue和PriorityQueue支持生产者-消费者模式,具有异步操作和可选的最大大小。

treeoflife6.png

1 同步原语 Synchronization primitives

以下是一些关键同步原语。

锁:

    Lock
    Event
    Condition

信号量:

    Semaphore
    BoundedSemaphore
    ASYNCIO锁API被设计成接近的类threading 模块(Lock,Event, Condition,
    Semaphore, BoundedSemaphore),但它没有超时参数。该 asyncio.wait_for()功能可用于在超时后取消任务。

2 锁具 Lock

示例

    class asyncio.Lock(*, loop=None)   # 非线程安全
        # 原始锁对象,基元锁是一种同步基元。
        # 原始锁只处于锁定 解锁两种状态 
          # 协程 已获得 acquire(),  与yield from 一起使用
          # release()
        yield from lock  # 锁支持上下文管理协议。应该用作上下文管理表达式
  • 获得锁

      lock = Lock()
      ...
      yield from lock
      try:
          ...
      finally:
    
  • 释放锁

          lock.release()
    
  • 上下文管理器

      lock = Lock()
      ....
      with (yield from lock):
         ...
    
  • 测试锁定对象的锁定状态

      if not lock.locked():
          yield from lock
      else:
         # lock is acquired
    

功能:

    是否获得锁 locked()   # 如果获得了锁,返回True
    协程 获取锁 acquire()
    释放锁 release()

3 事件 Event

Event 实现,异步等效于 threading.Event,实现事件对象的类。
事件管理一个标志(默认为false),该标志可用通过方法设置为true,并通过set()设置为false

    class asyncio.Event(*, loop=None)   # 非线程安全

方法

        clear()   # 内部标志位重置false,协程调用wait()将阻塞到set()被调用以再次将内部标志设置位true
        is_set() #True当且仅当北部标志为true才返回
        set()  # 将内部标志设置为true
        wait()   # 协程

4 触发条件 Condition

触发 条件的实现,异步等效于threading.Condition。

此类实现条件变量对象,条件变量运行一个或多个协程等待,直达他们被另一个协程通知。

如果没有给出lock参数为None,则必须是一个Lock对象,并且用作基础锁,否则将Lock创建一个新对象并将其用作基础锁

    class asyncio.Condition(lock=None, *, loop=None)  # 非线程安全

获取基础锁,此方法将阻塞到解锁,然后再将其设置为lock并返回True

        协程 acquire()    

默认情况夏,唤醒一个协程等待这个情况(如果有)如果在调用此方法时调用协程尚未获取锁定 引发错误 RuntimeError

        notify(n=1)  

如获得了基础锁,则返回

        locked()   

唤醒等待这种情况的所有协程。此方法类似 notify() 但此方法是唤醒所有等待的协程,如果调用此方法时被调用协程尚未获取锁定,则触发 RuntimeError

        notify_all()   

无返回,释放基础锁,将其重置为解锁状态然后返回。未锁定的锁被调用时,引发RuntimeError

        release()   

等到收到通知,如果调用此方法时协程尚未获取锁定,

        asyncio wait()   

此方法释放基础锁,然后进行阻塞 直到被notify()等类似方法唤醒为止。唤醒后,它将重新获取锁并返回True

        RuntimeError将触发

等到func变为真,func应为可调用的,结果解释为布尔值

        asyncio wait_for(func)   

5 信号量 Semaphores 信号

Semaphore 信号量实现。 此类管理一个内部计数器,计数器由每个acquire()调用递减,并由每个release()调用递增。

计数器永远不能低于0,当acquire()发现它为0时,将阻塞,直到其他协程调用release() 为止。

        class asyncio.Semaphore(value=1, *, loop=None)   
                    # 非线程安全

acquire 获取一个信号量,如果内部计数器在输入时大于零,将其递减一,并返回True。如果进入时为0,阻塞;等待其他协程调用release() 使其大于0,然后返回True

        asyncio acquire()    

locked 如果无法立即获取信号量返回 True

        locked()   

release释放信号量,使内部计数器加1,进入时为0,并且另一个协程正则等待再次变为0,唤醒该协程

        release()    

6 有界信号量

有界信号量实现,继承自Semaphore。 在release() 它是否将增加超过ValueError初始值的值

        class asyncio.BoundedSemaphore(value=1, *, loop=None)

7 队列集

源代码: Lib / asyncio / queues.py

    Queue
    PriorityQueue
    LifeQueue

ASYNCIO队列API被设计为接近的queue模块的类 asyncio.wait_for() 功能可用于在超时 后取消任务

8 队列

队列用于协程生产者和消费者协程,如果maxsize小于或等于零,队列大小无限。 如果maxsize大于0,当队列达到maxsize时将阻塞,直到被删除 yield from

    class asyncio.Queue(Maxsize=0, *, loop=None)   # >py3.44

压入和获取 put get
与标准库不同queue,可用可靠的知晓Queue的大小qsize(),因为单线程asyncio应用程序不会在 调用qsize()和在Queue上执行操作时被中断。

        put(), get()

empty 如果队列为空返回True,否则返回False

        empty()  

full 如果有maxsize个条目在队列,则返回True。 如果Queue使用参数maxsize=0, 则full()用于不会为True

        full()    

异步 get 从队列删除并返回一个元素。如果队列为空,则等待,直到队列有元素
async get()

get_nowait从队列中删除并返回一个项目,立即返回一个队列中的元素,如果队列有值,引发异常QueueEmpty

         get_nowait()  

async join 阻塞直到队列所有项目都已获得并处理,每当将项目添加到队列时,未完成任务数量将增加。 当未完成任务数降至0,join() 取消阻止
async join()

async put 项目放入队列。如果队列已满,请等待空闲插槽可用再添加到项目

        async put()  

put_nowait 不阻塞的放一个元素入队列。如果没有空闲槽位,引发QueueFull异常

        put_nowait()  

qsize 队列中的项目数

        qsize()  

task_done 前面排队的任务已经完成,即get出来的元素相关操作已经完成。

        task_done() # >py3.4.4  

maxsize 队列中可存放的元素数量

         maxsize  
目录
相关文章
|
4月前
|
Python
如何在Python中实现线程之间的同步和通信?
【2月更文挑战第17天】【2月更文挑战第51篇】如何在Python中实现线程之间的同步和通信?
55 5
|
4月前
|
Python
在Python中,如何保证多个线程之间的同步?
在Python中,如何保证多个线程之间的同步?
57 4
|
2月前
|
设计模式 机器学习/深度学习 测试技术
设计模式转型:从传统同步到Python协程异步编程的实践与思考
【7月更文挑战第15天】探索从同步到Python协程异步编程的转变,异步处理I/O密集型任务提升效率。async/await关键词定义异步函数,asyncio库管理事件循环。面对挑战,如思维转变、错误处理和调试,可通过逐步迁移、学习资源、编写测试和使用辅助库来适应。通过实践和学习,开发者能有效优化性能和响应速度。
45 3
|
3月前
|
数据挖掘 调度 开发者
Python并发编程的艺术:掌握线程、进程与协程的同步技巧
并发编程在Python中涵盖线程、进程和协程,用于优化IO操作和响应速度。`threading`模块支持线程,`multiprocessing`处理进程,而`asyncio`则用于协程。线程通过Lock和Condition Objects同步,进程使用Queue和Pipe通信。协程利用异步事件循环避免上下文切换。了解并发模型及同步技术是提升Python应用性能的关键。
84 5
|
2月前
|
Python
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
|
2月前
|
安全 API Python
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
`multiprocessing`是Python的一个标准库,用于支持生成进程,并通过管道和队列、信号量、锁和条件变量等同步原语进行进程间通信(IPC)。
|
2月前
|
IDE 开发工具 Python
【Python】已解决:pip安装第三方模块(库)与PyCharm中不同步的问题(PyCharm添加本地python解释器)
【Python】已解决:pip安装第三方模块(库)与PyCharm中不同步的问题(PyCharm添加本地python解释器)
267 0
|
4月前
|
数据采集 监控 调度
Python的进程,以及进程同步,守护进程详细解读
Python的进程,以及进程同步,守护进程详细解读
168 4
|
10月前
|
Python
126 python高级 - 同步应用
126 python高级 - 同步应用
45 0