簡體   English   中英

在 python(無線程)中限制並發 http 請求的最佳方法?

[英]Best way to limit concurrent http requests in python (no threads)?

我有興趣為異步 function 調用創建一個池(它們將是 HTTP 請求)但是我想在一個線程中完成所有事情。 這樣做的原因是產生多個線程會浪費資源(線程什么都不做,只是等待響應)。

import asyncio
import aiohttp

import some_library as pool

POOL_LIMIT = 3

urls = ["example.com/28409078",
"example.com/31145880",
"example.com/54622752",
"example.com/48008963",
"example.com/82016326",
"example.com/75587921",
"example.com/2988065",
"example.com/47574087",
"example.com/13478021",
"example.com/46041669"]

def get(url):
  # return some promise here

# now perform the async operations
pool(limit=POOL_LIMIT, urls, get)


是否有可以為我管理異步池的 python 庫? 在 Node.js 中,看起來有一個庫可以做一些接近我想做的事情: https://github.com/rxaviers/async-pool

在這里,我使用基本的asyncio函數實現了一個池。

在職的:

  • 池以 maxsize 任務開始
  • 當第一個任務完成時,它將下一個任務添加到隊列並打印其結果
  • 類似地,對於每個單獨的任務完成,它會添加另一個任務直到 maxsize

代碼:

import asyncio

async def pool(tasks, maxsize=3):
    pending = [tasks.pop(0) for _ in range(maxsize) if tasks]
    while pending:
        (done, pending) = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED)
        while True:
             if (not tasks) or (len(pending) >= maxsize):
                  break
             pending.add(tasks.pop(0))
        for task in done:
             print(task.result())
    print("POOL COMPLETED")

例如,您可以像這里一樣創建任務和池:

async def work(index, sleep_time):
    await asyncio.sleep(sleep_time)
    return f"task {index} done"

tasks = [work(i, 1) for i in range(10)]

現在運行任務調用 asyncio.run

asyncio.run(pool(tasks, 3))

這只會並行運行 3 個任務

我不知道是否有一個流行的圖書館。 這是一種簡單的方法:

async def get(url):
  # return some promise here

async def processQueue():
  while len(urls):
    url = urls.pop()
    await get(url)

async def main():
  await asyncio.gather(
    processQueue(),
    processQueue(),
    processQueue()
  )

asyncio.run(main())

你可能需要在 pop() 之前加一個鎖,我不確定。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM