#python #multithreading #python-3.x #buffering
#python #многопоточность #python-3.x #буферизация
Вопрос:
Я новичок в потоках и многопроцессорной обработке. У меня есть некоторый код, в котором я запускаю процесс, и я хотел, чтобы на выходе отображалось активное состояние ожидания чего-то вроде этого
wating....
Код похож на приведенный ниже:
импорт потоков время импорта
class ThreadExample(object):
def __init__(self):
self.pause = True
threading.Thread(target=self.second_thread).start()
# Some other processes
print("Waiting", end="")
while self.pause:
time.sleep(1)
print(".", end="")
print("Hooray!")
def second_thread(self):
print("timer started")
time.sleep(3)
self.pause = False
print("timer finished")
if __name__ == "__main__":
ThreadExample()
Когда я запускаю приведенный выше код, я получаю выходные данные:
timer started
Do something else..timer finished
.
Hooray!
не большой сюрприз, за исключением того, что в начале появляется только «таймер запущен», а остальная часть текста мгновенно появляется в конце.
Если я изменю строку print(«.», end=»») на print(«.»), я получу следующий вывод:
timer started
Do something else.
.
timer finished
.
Hooray
где точки появляются с шагом в 1 секунду, что и было моим намерением.
Есть ли способ получить «Ожидание …» в одной строке без end =»»?
И, во-вторых, я предполагаю, что это как-то связано с внутренними компонентами функции print(), а если нет, должен ли я выполнять потоковую обработку другим способом? Я не думаю, что проблема в GIL, поскольку я пробовал многопроцессорность.Обработал и получил тот же результат.
Ответ №1:
Вероятно, это связано с print
буферизацией. Он сбрасывается n
и в некоторых других случаях (например, переполнение буфера или выход из программы). Вместо print
того, чтобы попробовать это:
import sys
def unbuffered_print(msg):
sys.stdout.write(msg)
sys.stdout.flush()
...
unbuffered_print('.')
везде.
Комментарии:
1. Примечание: На современном Python (3.3 и выше)
flush=True
, чтобы сделать его сброшенным после печати , сохраняя при этом полную мощность / гибкостьprint(end='.', flush=True)
что илиprint('.', end='', flush=True)
также сделает свое дело.2. Спасибо, это очень полезно.