python - 有没有办法将 'stdin' 作为参数传递给 python 中的另一个进程?

标签 python multiprocessing stdin

我正在尝试创建一个使用 python 多处理模块的脚本。该脚本(我们称之为 myscript.py)将从另一个带有管道的脚本获取输入。

假设我这样调用脚本;

$ python writer.py | python myscript.py 

这是代码;

// writer.py
import time, sys

def main():
    while True:
        print "test"
        sys.stdout.flush()
        time.sleep(1)

main()

//myscript.py
def get_input():
    while True:
        text = sys.stdin.readline()
        print "hello " + text
        time.sleep(3)

if __name__ == '__main__':        
    p1 = Process(target=get_input, args=())
    p1.start()

这显然是行不通的,因为主进程和 p1 的 sys.stdin 对象是不同的。所以我试过这个来解决它,

//myscript.py
def get_input(temp):
    while True:
        text = temp.readline()
        print "hello " + text
        time.sleep(3)

if __name__ == '__main__':        
    p1 = Process(target=get_input, args=(sys.stdin,))
    p1.start()

但是我遇到了这个错误;

Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "in.py", line 12, in get_input
    text = temp.readline()
ValueError: I/O operation on closed file

所以,我猜 main 的标准输入文件已关闭,我无法从中读取。在这种情况下,如何将 main 的 stdin 文件传递​​给另一个进程?如果无法传递 stdin,我如何从另一个进程使用 main 的 stdin?

更新: 好的,我需要澄清我的问题,因为人们认为使用多处理并不是真正必要的。 像这样考虑 myscript.py

//myscript.py
def get_input():
    while True:
        text = sys.stdin.readline()
        print "hello " + text
        time.sleep(3)

def do_more_things():
    while True:
        #// some code here
        time.sleep(60*5)

if __name__ == '__main__':        
    p1 = Process(target=get_input, args=())
    p1.start()

    do_more_things()

因此,我确实需要与主函数(或其他子进程)并行运行 get_input() 函数。 对于冲突,我很抱歉,我的英语不错,我想我在这个问题上不清楚。如果你们能告诉我我是否可以在另一个进程中使用主进程 STDIN 对象,我将不胜感激。

提前致谢。

最佳答案

最简单的方法是交换 get_input()do_more_things(),即在父进程中读取 sys.stdin:

def get_input(stdin):
    for line in iter(stdin.readline, ''):
        print("hello", line, end='')
    stdin.close()

if __name__ == '__main__':
    p1 = mp.Process(target=do_more_things)
    p1.start()
    get_input(sys.stdin)

下一个最好的办法是为 get_input() 使用 Thread() 而不是 Process():

if __name__ == '__main__':
    t = Thread(target=get_input, args=(sys.stdin,))
    t.start()
    do_more_things()

如果以上方法没有帮助,您可以尝试 os.dup():

newstdin = os.fdopen(os.dup(sys.stdin.fileno()))
try: 
   p = Process(target=get_input, args=(newstdin,))
   p.start()    
finally:
   newstdin.close() # close in the parent
do_more_things()

关于python - 有没有办法将 'stdin' 作为参数传递给 python 中的另一个进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8976962/

相关文章:

python - 使用 pd.merge 映射两个数据帧

python - 只应打开一扇 window 时却打开了两扇 window

python - 使用 IMAP 提取 header 错误 TypeError : initial_value must be str or None, not bytes

python - 加速 Redis 服务器输入

python - 如何在使用 Pool.map() 进行多处理时解决内存问题?

shell - 如何在 vim 中将当前缓冲区或行作为 stdin 发送到 system()?

ruby - 如何将 Ruby 的 STDIN 传递给 Open3.popen3 调用的外部程序?

python - 为什么我的 python unittest 脚本在导入时调用我的脚本?

python - 如何在不同的 Python 多处理核心之间共享带有元组键的全局字典?

c - 在 C 中使用 fget 读取固定数量的字符