【问题标题】:Python: Run only one function asyncPython:只运行一个函数异步
【发布时间】:2020-05-14 17:31:31
【问题描述】:

我有一个大型遗留应用程序,它具有 一个 函数,该函数是异步执行的主要候选者。它受 IO 限制(网络和磁盘)并且不返回任何内容。 这是一个非常简单的类似实现:

import random
import time
import requests

def fetch_urls(site):
    wait = random.randint(0, 5)
    filename = site.split("/")[2].replace(".", "_")
    print(f"Will fetch {site} in {wait} seconds")
    time.sleep(wait)
    r = requests.get(site)
    with open(filename, "w") as fd:
        fd.write(r.text)

def something(sites):
    for site in sites:
        fetch_urls(site)
    return True

def main():
    sites = ["https://www.google.com", "https://www.reddit.com", "https://www.msn.com"]
    start = time.perf_counter()
    something(sites)
    total_time = time.perf_counter() - start
    print(f"Finished in {total_time}")

if __name__ == "__main__":
    main()

我的最终目标是更新 something 函数以异步运行 fetch_urls。 我无法更改 fetch_urls

我能找到的所有文档和教程都假定我的整个应用程序是异步的(从 async def main() 开始),但事实并非如此。 这是一个跨越多个模块的巨大应用程序,并且为单个函数重构所有内容看起来不正确。

据我所知,我需要创建一个循环,向其中添加任务并以某种方式调度它,但我尝试了许多不同的方法,但我仍然让所有东西一个接一个地运行——而不是同时运行。

如有任何帮助,我将不胜感激。谢谢!

【问题讨论】:

    标签: asynchronous


    【解决方案1】:

    回复我自己,似乎没有简单的方法可以使用异步来做到这一点。最终使用concurrent.futures

    import time
    import requests
    import concurrent.futures
    
    
    def fetch_urls(url, name):
        wait = 5
        filename = url.split("/")[2].replace(".", "_")
        print(f"Will fetch {name} in {wait} seconds")
        time.sleep(wait)
        r = requests.get(url)
        with open(filename, "w") as fd:
            fd.write(r.text)
    
    def something(sites):
        with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(fetch_urls, url["url"], url["name"]): (url)
                for url in sites["children"]
            }
            for future in concurrent.futures.as_completed(future_to_url):
                url = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r generated an exception: %s" % (url, exc))
        return True
    
    
    def main():
        sites = {
            "parent": "https://stackoverflow.com",
            "children": [
                {"name": "google", "url": "https://google.com"},
                {"name": "reddit", "url": "https://reddit.com"},
            ],
        }
        start = time.perf_counter()
        something(sites)
        total_time = time.perf_counter() - start
        print(f"Finished in {total_time}")
    

    【讨论】:

      猜你喜欢
      • 2019-05-22
      • 1970-01-01
      • 2022-11-22
      • 2021-04-30
      • 2019-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 2022-11-16
      相关资源
      最近更新 更多