Python多处理stdin输入

时间:2015-05-08 23:31:32

标签: windows python-3.x process multiprocessing stdin

在python 3.4 windows 7上编写和测试的所有代码。

我正在设计一个控制台应用程序,并且需要从命令行(win os)使用stdin来发出命令并更改程序的操作模式。该程序依赖于多处理来处理cpu绑定负载以传播到多个处理器。

我正在使用stdout监视该状态和一些基本的返回信息,并使用stdin发出命令,根据返回的控制台信息加载不同的子进程。

这是我发现问题的地方。我无法让多处理模块接受stdin输入,但是stdout正常工作。我想在stack找到了以下帮助所以我对它进行了测试,发现使用线程模块这一切都很有效,除了stdout的所有输出都被暂停,直到每次stdin由于GIL锁定而循环stdin阻止。

我会说我已成功完成了使用msvcrt.kbhit()实现的工作。但是,我无法帮助,但是想知道在多处理功能中是否存在某种错误,使得stdin无法读取任何数据。我尝试了很多方法,在使用多处理时没有任何效果。甚至尝试使用队列,但我没有尝试池或多处理的任何其他方法。

我也没有在我的linux机器上尝试这个,因为我专注于尝试让它工作。

这是简化的测试代码,它不能按预期运行(提醒这是用Python 3.4编写的 - win7):

import sys
import time
from multiprocessing import Process

def function1():
    while True:
        print("Function 1")
        time.sleep(1.33)

def function2():
    while True:
        print("Function 2")
        c = sys.stdin.read(1) # Does not appear to be waiting for read before continuing loop.
        sys.stdout.write(c) #nothing  in 'c'
        sys.stdout.write(".") #checking to see if it works at all.
        print(str(c)) #trying something else, still nothing in 'c'
        time.sleep(1.66)

if __name__ == "__main__":
    p1 = Process(target=function1)
    p2 = Process(target=function2)
    p1.start()
    p2.start()

希望有人可以说明这是否是预期的功能,如果我没有正确实现它,或者其他一些有用的信息。

感谢。

1 个答案:

答案 0 :(得分:5)

当你看一下multiprocessing.Process._bootstrap()的Pythons实现时,你会看到:

if sys.stdin is not None:
    try:
        sys.stdin.close()
        sys.stdin = open(os.devnull)
    except (OSError, ValueError):
        pass

您也可以使用以下方式确认:

>>> import sys
>>> import multiprocessing
>>> def func():
...     print(sys.stdin)
... 
>>> p = multiprocessing.Process(target=func)
>>> p.start()
>>> <_io.TextIOWrapper name='/dev/null' mode='r' encoding='UTF-8'>

os.devnull读取会立即返回空结果:

>>> import os
>>> f = open(os.devnull)
>>> f.read(1)
''

您可以使用open(0)

解决此问题
  

file 是一个字符串或字节对象,给出要打开的文件的路径名(绝对或相对于当前工作目录)或文件的整数文件描述符包裹即可。 (如果给出了文件描述符,则在关闭返回的I / O对象时关闭它,除非将closefd设置为False。)

"0 file descriptor"

  

文件描述符是与当前进程打开的文件对应的小整数。例如,标准输入通常是文件描述符0 ,标准输出是1,标准错误是2:

>>> def func():
...     sys.stdin = open(0)
...     print(sys.stdin)
...     c = sys.stdin.read(1)
...     print('Got', c)
... 
>>> multiprocessing.Process(target=func).start()
>>> <_io.TextIOWrapper name=0 mode='r' encoding='UTF-8'>
Got a