Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将大量数据写入stdin_Python_Subprocess - Fatal编程技术网

Python 将大量数据写入stdin

Python 将大量数据写入stdin,python,subprocess,Python,Subprocess,我正在向stdin写入大量数据 我如何确保它没有阻塞 p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE) p.stdin.write('A very very very large amount of data') p.stdin.flush() output = p.stdout.readline() 在我读了一个大字符串并对其进行了写入之后,它似乎挂在了p.stdin.write上 我有大量的文件,

我正在向stdin写入大量数据

我如何确保它没有阻塞

p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p.stdin.write('A very very very large amount of data')
p.stdin.flush()
output = p.stdout.readline()
在我读了一个大字符串并对其进行了写入之后,它似乎挂在了p.stdin.write上

我有大量的文件,这些文件将按顺序写入stdin>1k文件

所以我运行的是一个循环

#this loop is repeated for all the files
for stri in lines:
p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p.stdin.write(stri)
output = p.stdout.readline()
#do some processing
它不知怎的挂在了第400号文件上。该文件是一个带有长字符串的大文件

我怀疑这是一个阻塞问题

只有在从0迭代到1000时才会发生这种情况。但是,如果从文件400开始,则不会发生错误

您可能必须使用Popen.communicate

如果您将大量数据写入stdin,并且在此期间,子进程将生成输出到stdout,则在处理所有stdin数据之前,子进程的stdout缓冲区可能会变满。子进程阻塞对标准输出的写入,因为您没有读取它,并且在写入标准输入时被阻塞

Popen.communicate可用于同时写入stdin和读取stdout/stderr,以避免前面的问题

注意:Popen.communicate仅适用于输入和输出数据不太大的情况

更新: 如果您决定使用线程,这里有一个示例父进程和子进程实现,您可以根据自己的需要进行定制:

parent.py:

child.py:

注意:IOError在读/写线程上处理,以处理子进程退出/崩溃/终止的情况。

您可能必须使用Popen.communicate

如果您将大量数据写入stdin,并且在此期间,子进程将生成输出到stdout,则在处理所有stdin数据之前,子进程的stdout缓冲区可能会变满。子进程阻塞对标准输出的写入,因为您没有读取它,并且在写入标准输入时被阻塞

Popen.communicate可用于同时写入stdin和读取stdout/stderr,以避免前面的问题

注意:Popen.communicate仅适用于输入和输出数据不太大的情况

更新: 如果您决定使用线程,这里有一个示例父进程和子进程实现,您可以根据自己的需要进行定制:

parent.py:

child.py:


注意:IOError在读/写线程上处理,以处理子进程退出/崩溃/终止的情况。

要以可移植的方式避免死锁,请在单独的线程中写入子进程:

#!/usr/bin/env python
from subprocess import Popen, PIPE
from threading import Thread

def pump_input(pipe, lines):
    with pipe:
        for line in lines:
            pipe.write(line)

p = Popen(path, stdin=PIPE, stdout=PIPE, bufsize=1)
Thread(target=pump_input, args=[p.stdin, lines]).start()
with p.stdout:
    for line in iter(p.stdout.readline, b''): # read output
        print line,
p.wait()

请参见

要以可移植的方式避免死锁,请在单独的线程中写入子线程:

#!/usr/bin/env python
from subprocess import Popen, PIPE
from threading import Thread

def pump_input(pipe, lines):
    with pipe:
        for line in lines:
            pipe.write(line)

p = Popen(path, stdin=PIPE, stdout=PIPE, bufsize=1)
Thread(target=pump_input, args=[p.stdin, lines]).start()
with p.stdout:
    for line in iter(p.stdout.readline, b''): # read output
        print line,
p.wait()

请参见

看起来您需要这样做。您是想避免它被阻塞,还是只是担心在完成对标准输入管道的写入之前,当进程的输出填满标准输出管道时会出现死锁?我认为p.communicate会修复死锁,但它仍然会阻塞,直到所有的输入都被发送出去。它只是使用线程在内存中缓冲同时返回的任何内容。@DanD。嗨,你能进一步解释一下吗。我好像没拿到文件你正在运行的程序打印了什么?您似乎在为每一行写回一行,但程序是否可以打印更多的内容?类似地,它是在开始写响应行之前读取您的完整输入行,还是处理较短的数据位(例如逐字节)?@aceminer:我明白,我的问题是关于另一端的程序。它有时会为单个输入行返回两行或多行,还是保证只为一行返回一行?类似地,它是以字节流的形式对输入进行操作,还是在开始响应之前对发送的整行进行缓冲?如果是这两种情况中的前一种,您可能需要使用线程或类似的情况。p.如果您使用Python 3.3+进行通信,则需要超时,以确保您在编写响应的同时读取响应。看起来您需要这样做。是否要避免它被阻塞,或者只是担心当进程的输出在您完成对标准输入管道的写入之前填满标准输出管道时会出现死锁?我认为p.communicate会修复死锁,但它仍然会阻塞,直到所有的输入都被发送出去。它只是使用线程在内存中缓冲同时返回的任何内容。@DanD。嗨,你能进一步解释一下吗。我好像没拿到文件你正在运行的程序打印了什么?您似乎在为每一行写回一行,但程序是否可以打印更多的内容?类似地,它是在开始写响应行之前读取您的完整输入行,还是处理较短的数据位(例如逐字节)?@aceminer:我明白,我的问题是关于另一端的程序。它有时返回两个或多个值吗
单个输入行有多行,还是保证只返回一行对一行?类似地,它是以字节流的形式对输入进行操作,还是在开始响应之前对发送的整行进行缓冲?如果是上述两种情况中的前一种,您可能需要使用线程或类似的情况。p.如果您使用Python 3.3+进行通信,则需要超时,以确保您在编写的同时读取响应。@paszatorpisti是的,我怀疑这就是问题所在。我如何解决这个问题?Popen.communicate将无法工作,因为我正在重复写作。因此,我无法在每次需要处理流程时打开和关闭流程string@aceminer如果您正在动态传输输入/输出,则需要按Blckknght建议选择。然而,select存在可移植性问题,它在windows上经常会受到影响。出于这个原因,很久以前我写过一个多线程的hack,我并不为它在windows上克服这个问题而感到自豪,在不同的线程上读取stdout和写入stdin。实际上pythonselect文档说select只在windows上使用sockets…@aceminer还确保关闭子进程的stdout缓冲。否则,您可能会遇到这样一种情况:您在读取时被阻止,直到行尾,并且子进程缓冲了行尾。您是说在我的stdout上关闭stdout缓冲吗?对不起,我是新来的this@aceminer我指的是你作为一个孩子启动的计划的实施过程。如果子进程正在缓冲输出,而您正在等待一整行从其标准输出出来,则可能会挂断。这个bug只在我捕获一个C++应用程序的输出时发生了一次,它以一种奇怪的方式实现。事实上,如果你的应用程序没有弄乱标准,并且使用标准的默认方式,你就不必担心这个问题。@paszatorpisti是的,这就是我怀疑的问题所在。我如何解决这个问题?Popen.communicate将无法工作,因为我正在重复写作。因此,我无法在每次需要处理流程时打开和关闭流程string@aceminer如果您正在动态传输输入/输出,则需要按Blckknght建议选择。然而,select存在可移植性问题,它在windows上经常会受到影响。出于这个原因,很久以前我写过一个多线程的hack,我并不为它在windows上克服这个问题而感到自豪,在不同的线程上读取stdout和写入stdin。实际上pythonselect文档说select只在windows上使用sockets…@aceminer还确保关闭子进程的stdout缓冲。否则,您可能会遇到这样一种情况:您在读取时被阻止,直到行尾,并且子进程缓冲了行尾。您是说在我的stdout上关闭stdout缓冲吗?对不起,我是新来的this@aceminer我指的是你作为一个孩子启动的计划的实施过程。如果子进程正在缓冲输出,而您正在等待一整行从其标准输出出来,则可能会挂断。这个bug只在我捕获一个C++应用程序的输出时发生了一次,它以一种奇怪的方式实现。事实上,如果你的应用程序没有弄乱stdout并以标准的默认方式使用它,你就不必担心这个问题。
#!/usr/bin/env python
from subprocess import Popen, PIPE
from threading import Thread

def pump_input(pipe, lines):
    with pipe:
        for line in lines:
            pipe.write(line)

p = Popen(path, stdin=PIPE, stdout=PIPE, bufsize=1)
Thread(target=pump_input, args=[p.stdin, lines]).start()
with p.stdout:
    for line in iter(p.stdout.readline, b''): # read output
        print line,
p.wait()