Python多处理stdin输入

use*_*421 6 windows stdin process multiprocessing python-3.x

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

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

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

这是我发现问题的地方.我无法让多处理模块接受stdin输入,但是stdout正常工作.我认为在堆栈上找到了以下帮助所以我测试了它并发现使用线程模块这一切都很好用,除了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()
Run Code Online (Sandbox Code Playgroud)

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

谢谢.

Vyk*_*tor 6

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

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

您还可以使用以下方法确认:

>>> 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'>
Run Code Online (Sandbox Code Playgroud)

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

>>> import os
>>> f = open(os.devnull)
>>> f.read(1)
''
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方法解决此问题open(0):

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

" 0文件描述符 ":

文件描述符是与当前进程打开的文件相对应的小整数.例如,标准输入通常是文件描述符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
Run Code Online (Sandbox Code Playgroud)

  • 我认为应该是“os.fdopen(0)”。对我来说,“open(0)”抱怨它需要一个字符串。 (2认同)