input()在Windows 8(python 3.3)中阻止其他python进程
在使用多线程跨平台python3.3应用程序时,我遇到了一些奇怪的行为,我没有预料到,也不确定是否会发生。问题在于Windows 8在一个线程中调用input()在Windows 8(python 3.3)中阻止其他python进程,python,windows,multithreading,input,python-3.x,Python,Windows,Multithreading,Input,Python 3.x,在使用多线程跨平台python3.3应用程序时,我遇到了一些奇怪的行为,我没有预料到,也不确定是否会发生。问题在于Windows 8在一个线程中调用input()方法会阻塞其他线程,直到它完成为止。我已经在三台Linux、两台Windows 7和一台Windows 8计算机上测试了下面的示例脚本,这种行为仅在Windows 8计算机上观察到。这是Windows 8的预期行为吗 test.py: import subprocess, threading, time def ui(): i
input()
方法会阻塞其他线程,直到它完成为止。我已经在三台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')
更新:
在尝试其中一个建议时,我意识到我匆忙得出的结论遗漏了一些明显的东西。很抱歉,我的出发点不正确
正如Scholli建议的那样,只使用线程(没有子进程或python文件)会导致所有线程向前推进,因此问题实际上是在一个python进程中使用input()
,这将导致其他python进程阻塞/不运行(我不知道到底发生了什么)。此外,受影响的似乎只是python进程。如果我使用上面显示的相同代码(经过一些修改)执行带有subprocess.Popen的非python可执行文件,它们将按预期运行
总结如下:
- 使用子流程执行非python可执行文件:无论是否调用
,都能正常工作input()
- 使用子流程执行python可执行文件:如果在原始流程中调用了
,则创建的流程似乎不会运行李>input()
- 使用subprocess在新进程而不是原始进程中创建调用
的python进程:调用input()
会阻止“main”进程生成的所有python进程input()
旁注:我没有Windows 8平台,因此调试/测试可能会有点慢。因为Python 3.0-3.2中的
输入存在一些问题,此方法受到了影响,但改动很少
有可能我们又有了新的错误
您能否尝试以下变体,即raw\u input()
“back port”(在Python2.x中可用):
这是一个很好的问题
由于您依赖于input()
方法,该方法通常需要控制台输入
由于您有线程,所有线程都试图与控制台通信
因此,我建议您使用Producer-Consumer
概念,或者将所有输入定义为文本文件,并将文本文件传递给程序。如果您将copy.py
脚本重命名为其他内容,是否有帮助?当我启动Python解释器并键入import shutil
时,我得到一个错误,因为Python在我本地文件夹中的copy.py
文件上绊倒了。@Lukewoward:我怀疑它应该是copy\u loop.py
。您可以在Win 8上从源代码构建Python,从调试器运行Python test.py,然后,当所有线程都阻塞时,通过调试器暂停运行,查看其他线程阻塞了哪些线程。您可能能够找到阻塞调用阻塞8而不是7的原因。另一个问题是,如果您只使用线程而不使用子进程,是否仍然会发生这种情况:删除代码、放弃copy.py、缩减test.py,这样您就只有两个线程,一个执行输入,您是否得到相同的行为?然后重新引入代码片段,直到再次看到行为。对不起,没有简单的答案@EthanFurman:我想不会,因为提问者现在已经编辑了问题,将'copy\u loop.py'
替换为'copy.py'
。我认为这与问题无关。首先,您将展示一个与Python3.x一起使用的Python2.x的input()
,而不是raw\u input()。Python3的input()
是Python2的raw\u input()
(或多或少)。第二,在另一个调用中包装一个阻塞函数如何阻止它阻塞?您能详细说明一下吗?在我的程序中,所有python进程和线程只对input()进行一次调用(在主进程的线程中)。非阻塞输入法可能会解决这个问题,但这仅仅是解决问题的方法。
import shutil
import sys
src = sys.argv[1]
dst = sys.argv[2]
print('Copying \'{0}\' to \'{1}\''.format(src, dst))
shutil.copy(src, dst)
...
i = eval(input("-->"))
...