我正在尝试编写一个需要在单独的线程上运行套接字连接的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
正如您所看到的,从另一个线程打印后,在提示>>
不在新行中后添加输出。我怎么能这样做,以便它出现在一个新的行和提示符出现?
你可以做的是将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()
那很难。你的两个线程都共享相同的标准输出。因此,每个线程的输出会同时发送到stdout缓冲区,在那里它们以任意顺序打印。
你需要做的是协调两个线程的输出,这是一个难以破解的难题。甚至bash
也不这样做!
也就是说,也许您可以尝试使用lock
来确保您的线程以受控方式访问stdout
。退房:http://effbot.org/zone/thread-synchronization.htm