You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中能否将subprocess.Popen调用改为异步执行?

问题根因

你的判断完全准确,当前代码跑成同步模式的核心原因有两个:

  • 你用的subprocess.Popen是同步API,后续调用的whois.communicate()是阻塞式调用,执行这行代码时整个asyncio事件循环会被卡住,无法切换到其他协程执行任务,自然没法实现异步并发
  • 现有代码里queue.task_done()调用位置错误,还没等whois查询执行完成就标记任务处理完毕,会导致队列计数不准
修复方法

不要直接用标准库的同步subprocess模块,改用asyncio内置的异步子进程接口asyncio.create_subprocess_exec,对应的进程通信方法也是异步实现,调用时加await就会主动让出事件循环,不会阻塞其他任务执行。
修复后的完整worker代码如下:

import asyncio

async def worker(name, queue):
    while True:
        # 从队列获取待查询域名
        domain = await queue.get()

        print(f"\u001b[33m{name}\u001b[0m: {domain}", end="", flush=True)

        # 异步创建whois子进程,不会阻塞事件循环
        whois_proc = await asyncio.create_subprocess_exec(
            "whois",
            domain,
            stdout=asyncio.subprocess.PIPE
        )
        # 异步等待子进程执行完成,读取标准输出
        stdout, _ = await whois_proc.communicate()

        # 整个查询流程走完后再标记任务完成
        queue.task_done()

        print(
            " " + "\u001b[32mAVAILABLE\u001b[0m"
            if stdout == b"Domain Not Found\n"
            else "\u001b[31mUNAVAILABLE\u001b[0m"
        )
补充说明

需要控制查询并发量时,直接初始化对应数量的worker协程即可,比如要开20个并发查询就启动20个绑定同一个队列的worker任务,所有子进程调用都会异步调度,不会出现同步阻塞的问题。

内容的提问来源于stack exchange,提问作者iruoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:15:12