【Python】用装饰器限制协程并发量

该博客介绍了如何利用Python的asyncio模块实现并发限制,并展示了如何在运行过程中取消超过特定条件的协程。通过定义一个装饰器`limit`,结合Semaphore来控制并发数量,同时在主任务中监控并取消延迟超时的协程。文章强调了在并发控制和任务管理中的技巧和注意事项。
摘要由CSDN通过智能技术生成
from functools import wraps
from random import randint
import asyncio
from typing import Coroutine, List
from asyncio import Task

import nest_asyncio

nest_asyncio.apply()


def limit(max_coro):
    semphore = asyncio.Semaphore(max_coro)

    def _wrapper(func: Coroutine):
        @wraps(func)
        async def _worker(*args, **kwargs):
            async with semphore:
                return await func(*args, **kwargs)

        return _worker

    return _wrapper


# 并发量为 1
@limit(1)
async def request(idx):
    delay = randint(1, 1)
    print(idx, 'now requesting', 'delay', delay)
    await asyncio.sleep(delay)
    print(idx, 'delay', delay, 'done')
    return idx, delay

async def main():
    tasks: List[Task] = []

    for _ in range(6):
        task = asyncio.create_task(request(_))
        tasks.append(task)

    for task in asyncio.as_completed(tasks):
        _idx, delay = await task

        # 这里 running 的协程也会被取消
        # 可能需要用下标等方式标记当前返回的协程
        if delay > 2:
            # print(task.)
            for _task in tasks:
                print(_task.done())
                _task.cancel()
                await asyncio.sleep(0)
                # _task.
                # print('cancelled', '*' * 10)
                # print(_task)

            break

    await asyncio.wait(tasks)

原理很简单,就是装饰器 + 闭包。关于取消 running 协程的代码需要额外判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值