繁体   English   中英

从Python进程中的stdin读取?

[英]Read from stdin in Python Process?

我正在尝试从Python Process对象中读取sys.stdin,但我不断收到“ValueError:对已关闭文件的I / O操作”结果。 这是一个简单的例子:

import sys
from multiprocessing import Process

def do_something(input_data):
    for x in input_data:
        print x


input=sys.stdin

p = Process(target=do_something, args=(input,))
p.start() 
p.join() #Wait for Process to complete 

以上脚本始终失败:

Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "example.py", line 6, in do_something
    for x in input_data:
ValueError: I/O operation on closed file

当然,只需调用do_something(input)可以正常工作而无需使用Process。 创建一个Pipe()对象似乎有所帮助 - 我可以将stdin的内容写入Pipe并从进程中以字符串形式获取结果 - 但实际上我需要输入到类似文件的表单以进行某些下游操作。 我可以将内容转储到文件中并从Process中重新读取它,但这看起来非常笨拙,特别是如果stdin非常大。 是否有一些简单的方法可以从进程内的sys.stdin中读取?

这是因为在启动Process之前, stdin已关闭。 否则可能会发生父进程和子进程(或多个子进程)尝试从同一个stdin读取,这是一个坏主意。

在子进程中, sys.stdin实际上被重定向到/dev/null

from multiprocessing import Process
import sys

def test(*args):
    print(args)
    print(sys.stdin, sys.stdin.fileno())

if __name__ == '__main__':
    p = Process(target=test, args=(sys.stdin,))
    p.start()
    p.join()

应该打印类似于这样的东西:

(<closed file '<stdin>', mode 'r' at 0x7f3b4564b0c0>,)
(<open file '/dev/null', mode 'r' at 0x7f3b43a9e0c0>, 3)

这里传递的参数是对已关闭文件对象的引用,尝试使用它会引发您看到的错误。

你可以解决这个问题,通过使用os.dup()sys.stdin.fileno()在家长和文件描述符的副本返回传递给孩子作为参数,在这里你就可以使用os.fdopen()工作用它。

更干净的解决方案可能是读取父进程中的输入并使用multiprocessing.Queue 将其传递给子进程。

您必须在某个时候关闭您尝试写入的文件。 检查您的代码并尝试删除所有关闭文件的行( fileVariableName .close())并查看它是否有效。 如果是,则逐个重新添加它们以找到问题。 一旦找到导致问题的行,请尝试将其进一步移入程序(稍后调用),看看是否能解决问题。

编辑:改变

def do_something(input_data):
    for x in input_data:
        print x

def do_something():
    for x in sys.stdin:
        print x

并摆脱input = sys.stdin

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM