我有这个问题困扰我一段时间了,我似乎无法找到它的解决方案,我一直在使用subprocess.Popen()访问一个C ++应用程序,为我做了一些繁重的计算,但它继续冻结在Popen()。stdout.read(); 这是python代码:
process = subprocess.Popen(['/path/to/my/executable'], shell=False,
stdout=subprocess.PIPE, stdin=subprocess.PIPE)
process.stdin.write("Some String")
print process.stdout.read()#It freezes here
这是c ++代码:
int main(int argc, char** argv) {
...Prep work...
while (1) {
string input;
cin>>input;
...Some Work ...
cout<< response;
}
}
c ++代码在shell中完美运行,但我无法弄清楚为什么它会在python上冻结
答案 0 :(得分:3)
改为使用communicate()
:
import subprocess
process = subprocess.Popen(['app'], shell=False,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
out, err = process.communicate("Some String")
print out
另外,请确保在某个时候结束C ++过程。例如,当您到达输入流的末尾时:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
//...Prep work...
while (cin) { // <-- Will eventually reach the end of the input stream
string input;
cin >> input;
//...Some Work ...
string response = input;
cout << response;
}
}
在python的文档中有一个警告: http://docs.python.org/2/library/subprocess.html#subprocess.Popen.stdin(正上方)
它解释了当您写入外部应用程序时,数据可能会被放入队列中。此外,您的外部应用程序的输出也可能会被放入队列中。 communic()将&#34; flush&#34;您要发送到外部应用程序的内容,并等到应用程序终止。
使用communicate()
将获得整个外部应用程序在内存中的输出。如果它不实用(例如巨大的输出),则可以使用stdin和stdout对象进行写入或读取。你不需要照顾死锁&#34;:
import subprocess
process = subprocess.Popen(['app'], shell=False,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE)
process.stdin.write("Some String")
process.stdin.close() # <-- Makes sure the external app gets an EOF while
# reading its input stream.
for line in process.stdout.readlines():
print line
但即使采用这种技术,也要确保您提供给外部应用程序的输入足够小,以避免在写入时阻塞。
如果您的输入也很大,那么您必须确保您的读取和写入不会阻塞。使用线程很可能是一个不错的选择。
答案 1 :(得分:0)
通常我们需要非阻塞IO, 1)阅读所有回复,直到没有更多数据然后 2)向子进程发出一些东西, 重复1-2 使用线程也会有所帮助。