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

时间:2013-10-17 01:29:20

标签: 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("-->")
    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文件)会导致所有线程都向前推进,所以问题实际上是在一个python进程中使用input()将导致其他python进程阻塞/不运行(I不知道到底发生了什么。此外,它似乎只是受影响的python进程。如果我使用上面显示的相同代码(带有一些修改)来执行带有subprocess.Popen的非python可执行文件,它们将按预期运行。

总结:

  • 使用子进程执行非python可执行文件:无论是否调用input(),都可以按预期工作。
  • 使用子进程执行python可执行文件:如果在原始进程中调用input(),则创建的进程似乎不会运行。
  • 使用subprocess在新进程中调用input()而不是原始进程来创建python进程:对input()的调用会阻止'main'进程生成的所有python进程。

备注:我没有Windows 8平台,因此调试/测试可能会有点慢。

2 个答案:

答案 0 :(得分:1)

由于 Python 3.0-3.2 中的input存在多个问题,因此该方法受到的影响很小。

我们可能会再次遇到新的错误。

您可以尝试以下变体,即raw_input()“后端口”(可在 Python 2.x 中使用):

...
i = eval(input("-->"))
...

答案 1 :(得分:1)

这是一个非常好的问题,

因为你依赖input()方法,这通常需要控制台输入,

因为你有线程,所有线程都试图与控制台通信,

因此,我建议您使用Producer-Consumer概念或定义文本文件的所有输入,并将文本文件传递给程序。