Search code examples
python-3.xconsole-applicationwindows-console

Printing from other thread when waiting for input()


I am trying to write a shell that needs to run socket connections on a seperate thread. On my testings, when print() is used while cmd.Cmd.cmdloop() waiting for input, the print is displaying wrong.

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()

When the above command runs, here is what happens:

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

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

As you can see, printing from another threads add output after prompt >> not in a new line. How can I do it so that it appears in a new line and prompt appears?


Solution

  • What you can do, is redirect stdout from your core.shell.Shell to a file like object such as StringIO. You would also redirect the output from your thread into a different file like object.

    Now, you can have some third thread read both of these objects and print them out in whatever fashion you want.

    You said core.shell.Shell inherits from cmd.Cmd, which allows redirection as a parameter to the constructor:

    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()