Печать из другого потока при ожидании ввода () - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь написать оболочку, которая должна запускать соединения с сокетами в отдельном потоке.В моих тестах, когда 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

Как видите, печать из других потоков добавляет вывод после подсказки >> не в новой строке.Как я могу сделать так, чтобы он отображался в новой строке и появлялся запрос?

Ответы [ 2 ]

1 голос
/ 05 апреля 2019

Что вы можете сделать, это перенаправить stdout из вашего core.shell.Shell в файл, подобный объекту, например StringIO . Вы также перенаправили бы вывод из вашего потока в другой файл, подобный объекту.

Теперь вы можете попросить какой-нибудь третий поток прочитать оба этих объекта и распечатать их любым удобным для вас способом.

Вы сказали, что 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()
0 голосов
/ 05 апреля 2019

Это довольно сложно.Обе ваши темы используют один и тот же стандартный вывод.Таким образом, выходные данные каждого из этих потоков одновременно отправляются в буфер stdout, где они печатаются в произвольном порядке.

То, что вам нужно сделать, это скоординировать вывод из обеих нитей, и это крепкий орешек.Даже bash этого не делает!

Тем не менее, возможно, вы можете попробовать использовать lock, чтобы убедиться, что ваши потоки обращаются к stdout контролируемым образом.Проверить: http://effbot.org/zone/thread-synchronization.htm

...