Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python线程中正在进行多个stdout w/flush_Python_Multithreading_Stdout - Fatal编程技术网

Python线程中正在进行多个stdout w/flush

Python线程中正在进行多个stdout w/flush,python,multithreading,stdout,Python,Multithreading,Stdout,我有一小段代码,我做了测试,并希望调试问题,而不必修改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 = cou

我有一小段代码,我做了测试,并希望调试问题,而不必修改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。然后为其他线程提供一个线程安全通道,以分派要输出的数据

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

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

Threads
#1: 0
#2: 0
例子 请注意,在向线程传递参数时存在一些陷阱,我还使用了一些技巧来确保安全退出,例如使线程成为守护进程。没有使用换行符,因为
\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)

打印到标准输出不是线程安全的。使用
日志记录
模块,实现某种锁定,或者将打印移动到另一个线程。我使用stdout是因为我喜欢它显示(例如)一个数字的方式,然后刷新它并在它的旧位置打印一个新的。因此,为输出创建一个固定点,而不是让它为每个数字创建一个新行来打印它。@BlackVikingPro欢迎使用StackOverflow!如果有任何答案有助于解决您的问题或给您提供有用的见解,请确保对其进行投票,并在问题得到您喜欢的解决后选择最佳答案:)