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

如何解决subprocess.stdout.readline()无数据时的阻塞问题?

解决subprocess.stdout.readline()阻塞超时问题

原代码的核心问题是proc.stdout.readline()会永久阻塞,导致循环的总超时判断完全失效——只要readline卡住,程序就不会回到循环条件检查步骤。

方案一:用select模块实现带超时的逐行读取

通过select.select()监听标准输出的可读状态,每次等待数据时设置一个短超时,既能实时读取输出,又能定期检查总超时是否到达:

import subprocess
import time
import select

cmd = ["node", "transformerMonitor.js", "-h", "sample.com", "-s", "123"]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
total_timeout = 120
start_time = time.time()
poll_interval = 1  # 单次等待数据的超时时间(秒)

while time.time() - start_time < total_timeout:
    # 检查stdout是否有可读数据,超时时间为poll_interval
    ready, _, _ = select.select([proc.stdout], [], [], poll_interval)
    if ready:
        out = proc.stdout.readline()
        if not out:  # 读取到空内容,说明子进程已终止
            break
        print(out.strip())
    # 超时后自动回到循环,判断总超时是否触发

# 清理子进程,避免僵尸进程
proc.terminate()
proc.wait()

方案二:用communicate()实现整体超时(适合非实时逐行场景)

如果不需要实时逐行处理输出,可以直接用communicate(timeout)设置整体超时,超时后终止子进程:

import subprocess

cmd = ["node", "transformerMonitor.js", "-h", "sample.com", "-s", "123"]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, text=True)
total_timeout = 120

try:
    stdout, stderr = proc.communicate(timeout=total_timeout)
    for line in stdout.splitlines():
        print(line)
except subprocess.TimeoutExpired:
    proc.terminate()
    proc.wait()
    print("设备无响应,已超时退出")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:15:19