Работая над многопоточным кросс-платформенным приложением python3.3, я наткнулся на какое-то странное поведение, которого я не ожидал, и не уверен, что этого не ожидается. Проблема в Windows 8, вызывающая метод input()
в одном потоке, блокирует другие потоки, пока не завершится. Я проверил приведенный ниже пример script на трех Linux, двух компьютерах под управлением Windows 7 и Windows 8, и это поведение наблюдается только на компьютере под управлением Windows 8. Является ли это ожидаемым поведением для Windows 8?
test.py:
import subprocess, threading, time
def ui():
i = input("-->")
print(i)
def loop():
i = 0
f = 'sky.{}'.format(i)
p = subprocess.Popen(['python', 'copy.py', 'sky1', f])
t = time.time()
while time.time() < t+15:
if p.poll() != None:
print(i)
time.sleep(3)
i+=1
f = 'sky.{}'.format(i)
p = subprocess.Popen(['python', 'copy.py', 'sky1', f])
p.terminate()
p.wait()
def start():
t1 = threading.Thread(target=ui)
t2 = threading.Thread(target=loop)
t1.start()
t2.start()
return t2
t2 = start()
t2.join()
print('done')
copy.py:
import shutil
import sys
src = sys.argv[1]
dst = sys.argv[2]
print('Copying \'{0}\' to \'{1}\''.format(src, dst))
shutil.copy(src, dst)
Обновление: Пробовав одно из предложений, я понял, что я бросился к выводу, лишившись чего-то очевидного. Я приношу свои извинения за то, что вы пришли к ложному началу.
Так как Schollii предложил просто использовать потоки (без подпроцессов или файлов python), все процессы, делающие продвижение вперед, тем самым на самом деле используют input()
в одном процессе python, будут блокировать/не запускать другие процессы python (я не точно знаю, что происходит). Кроме того, это, по-видимому, только процессы python, которые затронуты. Если я использую тот же код, показанный выше (с некоторыми изменениями) для выполнения исполняемых файлов, отличных от python, с подпроцессом .Popen они будут работать как ожидалось.
Подводя итог:
- Использование подпроцесса для выполнения исполняемого файла, отличного от python: работает как ожидалось с помощью и без вызовов
input()
. - Использование подпроцесса для выполнения исполняемого файла python: созданные процессы не запускаются, если в исходном процессе выполняется вызов
input()
. - Используйте подпроцесс для создания процессов python с вызовом
input()
в новом процессе, а не в исходном процессе: вызовinput()
блокирует все процессы python, порожденные "основным" процессом.
Боковое примечание: у меня нет платформы Windows 8, поэтому отладка/тесты могут быть немного медленными.