subprocess.Popen.stdout - 实时读取标准输出(再次)

Vla*_*hev 12 python subprocess stdout popen

同样,同样的问题.
原因是 - 阅读以下内容后仍然无法使其正常工作:

我的情况是我有一个用C编写的控制台应用程序,让我们在循环中采用这个代码:

tmp = 0.0;   
printf("\ninput>>"); 
scanf_s("%f",&tmp); 
printf ("\ninput was: %f",tmp); 
Run Code Online (Sandbox Code Playgroud)

它不断读取一些输入并写入一些输出.

我与它交互的python代码如下:

p=subprocess.Popen([path],stdout=subprocess.PIPE,stdin=subprocess.PIPE)
p.stdin.write('12345\n')
for line in p.stdout: 
    print(">>> " + str(line.rstrip())) 
    p.stdout.flush() 
Run Code Online (Sandbox Code Playgroud)

到目前为止,每当我读取表单时,p.stdout它总是等待,直到进程终止然后输出一个空字符串.我尝试了很多东西 - 但结果仍然相同.

我尝试过Python 2.6和3.1,但版本没关系 - 我只需要让它在某个地方工作.

Jim*_*nis 4

尝试在子进程的管道中写入和读取是很棘手的,因为默认缓冲在两个方向上进行。当一个或另一个进程(父进程或子进程)从空缓冲区读取数据、写入已满缓冲区或在系统库刷新数据之前对正在等待数据的缓冲区进行阻塞读取时,很容易出现死锁。

对于更少量的数据,该Popen.communicate()方法可能就足够了。但是,对于超出其缓冲的数据,您可能会遇到停滞的进程(类似于您已经看到的?)

您可能想要查找有关使用该fcntl模块以及使一个或另一个(或两个)文件描述符成为非阻塞的详细信息。当然,在这种情况下,您必须将所有对这些文件描述符的读取和/或写入包装在适当的异常处理中,以处理“EWOULDBLOCK”事件。(我不记得为这些引发的确切 Python 异常)。

一种完全不同的方法是让您的父进程使用select模块并os.fork()...以及在直接处理任何文件 dup() 后让子进程访问execve()目标程序。(基本上,您将重新实现部分内容,Popen()但使用不同的父文件描述符(PIPE)处理。

顺便说一句,.communicate,至少在 Python 2.5 和 2.6 标准库中,只能处理大约 64K 的远程数据(在 Linux 和 FreeBSD 上)。该数字可能会因各种因素而异(可能包括用于编译 Python 解释器的构建选项,或链接到它的 libc 版本)。它不仅仅受可用内存的限制(尽管 JF Sebastian 的主张相反),而是限制为一个小得多的值。


归档时间:

查看次数:

12679 次

最近记录:

10 年,6 月 前