【问题标题】:Printing from other thread when waiting for input()等待输入()时从其他线程打印
【发布时间】:2019-08-27 12:54:32
【问题描述】:

我正在尝试编写一个需要在单独的线程上运行套接字连接的 shell。在我的测试中,当使用print()cmd.Cmd.cmdloop() 等待输入时,打印显示错误。

from core.shell import Shell
import time
import threading


def test(shell):
    time.sleep(2)
    shell.write('Doing test')


if __name__ == '__main__':
    shell = Shell(None, None)

    testThrd = threading.Thread(target=test, args=(shell,))

    testThrd.start()

    shell.cmdloop()

当上述命令运行时,会发生以下情况:

python test.py
Welcome to Test shell.  Type help or ? to list commands.

>>asd
*** Unknown syntax: asd
>>[17:59:25] Doing test

如您所见,从另一个线程打印会在提示 >> 之后添加输出,而不是在新行中。我怎样才能让它出现在新行中并出现提示?

【问题讨论】:

  • 我在core.shell 上找不到任何文档,但是如果您可以重定向Shell 的输出,那么您可以很容易地实现管理标准输出...。这取决于什么该模块支持。
  • 这是一个自定义创建的模块,继承cmd.Cmd 类。 docs.python.org/3/library/cmd.html

标签: python-3.x console-application windows-console


【解决方案1】:

这是相当困难的。您的两个线程都共享相同的标准输出。因此,这些线程中的每一个的输出都会同时发送到您的标准输出缓冲区,在那里它们以任意顺序打印。

您需要做的是协调两个线程的输出,这是一个难以破解的难题。即使bash 也不这样做!

也就是说,也许您可​​以尝试使用lock 来确保您的线程以受控方式访问stdout。签出:http://effbot.org/zone/thread-synchronization.htm

【讨论】:

  • 我想在Shell 类中添加一个do_print(),但这会在shell 中暴露打印命令。使用queue 也不起作用,因为input() 阻塞了主线程。
【解决方案2】:

您可以做的是将stdout 从您的core.shell.Shell 重定向到类似对象的文件,例如StringIO。您还可以将线程的输出重定向到不同的文件,如 object.

现在,您可以让第三个线程读取这两个对象并以您想要的任何方式将它们打印出来。

你说core.shell.Shell继承自cmd.Cmd,它允许重定向作为构造函数的参数:

import io
import time
import threading

from core.shell import Shell

def test(output_obj):
    time.sleep(2)
    print('Doing test', file=output_obj)

cmd_output = io.StringIO()
thr_output = io.StringIO()
shell = Shell(stdout=cmd_output)

testThrd = threading.Thread(target=test, args=(thr_output,))
testThrd.start()

# in some other process/thread
cmd_line = cmd_output.readline()
thr_line = thr_output.readline()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    相关资源
    最近更新 更多