[英]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.