如何避免Python程序在读取连续进程输出时挂起?

DDD
发布: 2024-11-01 09:47:02
原创
335 人浏览过

How to Avoid Python Programs Hanging When Reading Continuous Process Output?

在 Python 中停止进程输出读取而不挂起

背景

当将 Python 的 os.popen() 函数与产生连续输出的工具一起使用时,尝试读取输出时程序经常挂起。

os.popen() 问题

有问题的行进程 = os.popen("top").readlines() 由于以下原因暂停程序readlines(),它尝试一次读取整个进程的输出。

使用 subprocess.Popen() 的解决方案

要解决此问题,请使用 subprocess.Popen() 而不是 os.popen ()。这是一个更正的示例:

<code class="python">import subprocess
import time
import os

# Start "top" process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Wait for 2 seconds
time.sleep(2)

# Send kill signal to "top" process
os.popen("killall top")

# Read process output
output, _ = process.communicate()
print(output.decode())</code>
登录后复制

此修改后的代码:

  • 使用 communications() 而不是 readlines() 捕获变量中的进程输出。
  • 向“顶部”进程发送终止信号。
  • 声明进程 I/O 流的文件结束并退出程序。

类似尾部的方法

如果只需要进程输出的一部分,可以使用类似尾部的解决方案来捕获特定数量的行。

基于线程的方法

捕获进程在单独的线程中输出,请尝试以下操作:

<code class="python">import collections
import subprocess
import threading

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Define function to read process output in a thread
def read_output(process):
    for line in iter(process.stdout.readline, ""):
        ...  # Implement your logic here to process each line

# Create and start a thread for reading and processing output
reading_thread = threading.Thread(target=read_output, args=(process,))
reading_thread.start()

# Wait for 2 seconds, then terminate the process
time.sleep(2)
process.terminate()

# Wait for the reading thread to complete
reading_thread.join()</code>
登录后复制

signal.alarm() 方法

您还可以使用 signal.alarm() 在指定超时后终止进程:

<code class="python">import collections
import signal
import subprocess

# Define signal handler
def alarm_handler(signum, frame):
    # Raise an exception to terminate the process reading
    raise Exception

# Set signal handler and alarm for 2 seconds
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(2)

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Capture process output
number_of_lines = 200
q = collections.deque(maxlen=number_of_lines)
for line in iter(process.stdout.readline, ""):
    q.append(line)

# Cancel alarm
signal.alarm(0)

# Print captured output
print(''.join(q))</code>
登录后复制

threading.Timer 方法

或者,您可以使用 threading.Timer 来安排进程终止:

<code class="python">import collections
import subprocess
import threading

# Define function to terminate the process
def terminate_process(process):
    process.terminate()

# Start process with stdout redirection
process = subprocess.Popen(["top"], stdout=subprocess.PIPE)

# Create and start a timer to terminate process in 2 seconds
timer = threading.Timer(2, terminate_process, [process])
timer.start()

# Capture process output
number_of_lines = 200
q = collections.deque(process.stdout, maxlen=number_of_lines)

# Cancel timer
timer.cancel()

# Print captured output
print(''.join(q))</code>
登录后复制

以上是如何避免Python程序在读取连续进程输出时挂起?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!