input()在Windows 8(python 3.3)中阻止其他python进程

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

在使用多线程跨平台python3.3应用程序时,我遇到了一些奇怪的行为,我没有预料到,也不确定是否会发生。问题在于Windows 8在一个线程中调用
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在新进程而不是原始进程中创建调用
    input()
    的python进程:调用
    input()
    会阻止“main”进程生成的所有python进程

旁注:我没有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("-->"))
...