首頁  >  文章  >  後端開發  >  如何避免 Python 程式在讀取進程輸出時掛起?

如何避免 Python 程式在讀取進程輸出時掛起?

Susan Sarandon
Susan Sarandon原創
2024-11-02 13:54:29413瀏覽

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

停止讀取 Python 中的進程輸出而不掛起?

問題:

Python 程式需要與外部互動連續產生輸出的過程(例如「上」)。但是,直接讀取輸出可能會導致程式無限期掛起。

解決方案:

為了防止掛起,必須在以下情況下採用非阻塞或非同步機制:讀取過程輸出。以下是一些可能的方法:

假脫機暫存檔案(建議)

此方法利用專用檔案物件來儲存進程輸出。

#! /usr/bin/env python<br>導入子程序<br>導入臨時檔案<br>導入時間<p>def main():</p><pre class="brush:php;toolbar:false"># Open a temporary file (automatically deleted on closure)
f = tempfile.TemporaryFile()

# Start the process and redirect stdout to the file
p = subprocess.Popen(["top"], stdout=f)

# Wait for a specified duration
time.sleep(2)

# Kill the process
p.terminate()
p.wait()

# Rewind and read the captured output from the file
f.seek(0)
output = f.read()

# Print the output
print(output)
f.close()

if 名稱 == "__main__":

main()

基於執行緒的輸出讀取

這種方法採用單獨的執行緒來連續讀取進程輸出,同時主執行緒繼續執行其他任務。

導入集合<br>導入子程序<br>導入執行緒<br>導入時間<p>def read_output(process,append):</p><pre class="brush:php;toolbar:false">for line in iter(process.stdout.readline, ""):
    append(line)

def main():
# Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

# Create a thread for output reading
q = collections.deque(maxlen=200)
t = threading.Thread(target=read_output, args=(process, q.append))
t.daemon = True
t.start()

# Wait for the specified duration
time.sleep(2)

# Print the saved output
print(''.join(q))

if 名稱

== "__main__":
main()


al.alarm ()(僅限Unix)

此方法使用Unix 訊號在指定逾時後終止進程,無論是否已讀取所有輸出。

導入集合<pre class="brush:php;toolbar:false">pass
導入訊號

導入子程序

raise Alarm
class Alarm(Exception):

# Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

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

try:
    # Read and save a specified number of lines
    q = collections.deque(maxlen=200)
    for line in iter(process.stdout.readline, ""):
        q.append(line)
    signal.alarm(0)  # Cancel alarm
except Alarm:
    process.terminate()
finally:
    # Print the saved output
    print(''.join(q))
def Alarm_handler(signum,🎜>

def Alarm_handler(signum,,) :

main()
def main():

if

名稱

== "__main__":


== "__main__":

# Start the process and redirect stdout
process = subprocess.Popen(["top"], stdout=subprocess.PIPE, close_fds=True)

# Create a timer for process termination
timer = threading.Timer(2, process.terminate)
timer.start()

# Read and save a specified number of lines
q = collections.deque(maxlen=200)
for line in iter(process.stdout.readline, ""):
    q.append(line)
timer.cancel()

# Print the saved output
print(''.join(q))
threading.Timer

此方法使用計時器在指定的逾時後終止程序。它適用於 Unix 和 Windows 系統。

導入集合<pre class="brush:php;toolbar:false">main()
導入子程序

導入執行緒

def main():

if

name


if

name

args = sys.argv[1:]
if not args:
    args = ['top']

# Start the process and redirect stdout
process = subprocess.Popen(args, stdout=subprocess.PIPE, close_fds=True)

# Save a specified number of lines
q = collections.deque(maxlen=200)

# Set a timeout duration
timeout = 2

now = start = time.time()
while (now - start) < timeout:
    line = process.stdout.readline()
    if not line:
        break
    q.append(line)
    now = time.time()
else:  # On timeout
    process.terminate()

# Print the saved output
print(''.join(q))
if

name

if
main()
name

if name

if 名稱 == "__main__":沒有線程,沒有訊號此方法使用簡單的基於時間的循環,用於檢查進程輸出,如果超過指定逾時則將其終止。
導入集合導入子程序導入系統導入時間 def main():if 名稱 == "__main__":
注意:儲存的行數可以依照需要透過設定deque資料結構的'maxlen'參數來調整。

以上是如何避免 Python 程式在讀取進程輸出時掛起?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn