gpt4 book ai didi

python - Python 线程中进行多个 stdout w/flush

转载 作者:太空宇宙 更新时间:2023-11-03 15:13:24 24 4
gpt4 key购买 nike

我编写了一小段代码来测试并希望调试问题,而无需修改 Python 主小程序中的代码。这让我可以构建这段代码:

#!/usr/bin/env python
import sys, threading, time

def loop1():
count = 0
while True:
sys.stdout.write('\r thread 1: ' + str(count))
sys.stdout.flush()
count = count + 1
time.sleep(.3)
pass
pass

def loop2():
count = 0
print ""
while True:
sys.stdout.write('\r thread 2: ' + str(count))
sys.stdout.flush()
count = count + 2
time.sleep(.3)
pass

if __name__ == '__main__':
try:
th = threading.Thread(target=loop1)
th.start()

th1 = threading.Thread(target=loop2)
th1.start()
pass
except KeyboardInterrupt:
print ""
pass
pass

我对这段代码的目标是能够让这两个线程同时以 stdout 格式显示输出(带有刷新),然后并排或其他。问题是我假设因为它正在刷新每个字符串,所以默认情况下它会刷新另一个字符串。如果可能的话,我不太知道如何让它发挥作用。

如果你只运行其中一个线程,它就可以正常工作。但是,我希望能够在终端输出中同时运行两个线程,并使用它们自己的字符串运行。这是一张显示我得到的图片:

终端截图

如果您需要更多信息,请告诉我。提前致谢。

最佳答案

与其让每个线程都输出到 stdout,更好的解决方案是让一个线程独占控制 stdout。然后为其他线程提供一个线程安全通道来调度要输出的数据。

实现这一目标的一个好方法是共享 Queue所有线程之间。确保只有输出线程在将数据添加到队列后才访问数据。

输出线程可以存储来自每个其他线程的最后一条消息,并使用该数据很好地格式化标准输出。这可以包括清除输出以显示类似的内容,并在每个线程生成新数据时更新它。

Threads
#1: 0
#2: 0

示例

做出了一些决定来简化此示例:

  • 向线程提供参数时需要注意一些问题。
  • 当主线程退出时,守护线程会自行终止。它们用于避免增加这个答案的复杂性。在长时间运行或大型应用程序上使用它们可能会带来问题。其他问题讨论how to exit a multithreaded application不会泄漏内存或锁定系统资源。您需要考虑您的程序需要如何发出退出信号。考虑使用 asyncio 来避免这些注意事项。
  • 不使用换行符,因为 \r 回车符无法清除整个控制台。它们只允许重写当前行。
import queue, threading
import time, sys

q = queue.Queue()
keepRunning = True

def loop_output():
thread_outputs = dict()

while keepRunning:
try:
thread_id, data = q.get_nowait()
thread_outputs[thread_id] = data
except queue.Empty:
# because the queue is used to update, there's no need to wait or block.
pass

pretty_output = ""
for thread_id, data in thread_outputs.items():
pretty_output += '({}:{}) '.format(thread_id, str(data))

sys.stdout.write('\r' + pretty_output)
sys.stdout.flush()
time.sleep(1)

def loop_count(thread_id, increment):
count = 0
while keepRunning:
msg = (thread_id, count)
try:
q.put_nowait(msg)
except queue.Full:
pass

count = count + increment
time.sleep(.3)
pass
pass

if __name__ == '__main__':
try:
th_out = threading.Thread(target=loop_output)
th_out.start()

# make sure to use args, not pass arguments directly
th0 = threading.Thread(target=loop_count, args=("Thread0", 1))
th0.daemon = True
th0.start()

th1 = threading.Thread(target=loop_count, args=("Thread1", 3))
th1.daemon = True
th1.start()

# Keep the main thread alive to wait for KeyboardInterrupt
while True:
time.sleep(.1)

except KeyboardInterrupt:
print("Ended by keyboard stroke")
keepRunning = False
for th in [th0, th1]:
th.join()

示例输出:

(Thread0:110) (Thread1:330)

关于python - Python 线程中进行多个 stdout w/flush,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44060516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com