2005年06月29日 星期三 13:51
我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 的输出,而想先得到第一部分的输出。 例如,假设外部程序是以下python代码: test.py: import sys, time print 'hello'*500 sys.stdout.flush() time.sleep(100) print 'world'*500 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 有输出,即前500个'hello'。我的程序是这样写的: import os, select cmd = 'python test.py' pin, pout = os.popen2(cmd) select.select([pout], [], [], timeout)[0] pout.read() 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 谁知道这段代码应该如何正确书写?代码运行在Linux下。 -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月29日 星期三 14:08
Skipped content of type multipart/mixed-------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/x-pkcs7-signature Size: 3066 bytes Desc: not available Url : http://lists.exoweb.net/pipermail/python-chinese/attachments/20050629/e587cf13/smime.bin
2005年06月29日 星期三 14:27
你这里不应该用read 应该用readline 2005/6/29, Hong Yuan <hongyuan at homemaster.cn>: > 我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 > 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 > 的输出,而想先得到第一部分的输出。 > > 例如,假设外部程序是以下python代码: > > test.py: > import sys, time > print 'hello'*500 > sys.stdout.flush() > time.sleep(100) > print 'world'*500 > > 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 > 有输出,即前500个'hello'。我的程序是这样写的: > > import os, select > cmd = 'python test.py' > pin, pout = os.popen2(cmd) > select.select([pout], [], [], timeout)[0] > pout.read() > > 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 > 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 > > 谁知道这段代码应该如何正确书写?代码运行在Linux下。 > > -- > HONG Yuan > > 大管家网上建材超市 > http://www.homemaster.cn > > _______________________________________________ > python-chinese list > python-chinese at lists.python.cn > http://python.cn/mailman/listinfo/python-chinese > -- I'm the one, powered by nEO
2005年06月29日 星期三 14:32
select用于socket本来就没有问题的,但对于进程间的管道好像是有问题的。
Neo Chan (netkiller) wrote:
>
>大同小意..改改就成..自己研究去吧.
>
>import select
>import socket
>import time
>
>PORT = 8037
>
>TIME1970 = 2208988800L
>
>service = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>service.bind(("", PORT))
>service.listen(1)
>
>print "listening on port", PORT
>
>while 1:
> is_readable = [service]
> is_writable = []
> is_error = []
> r, w, e = select.select(is_readable, is_writable, is_error, 1.0)
> if r:
> channel, info = service.accept()
> print "connection from", info
> t = int(time.time()) + TIME1970
> t = chr(t>>24&255) + chr(t>>16&255) + chr(t>>8&255) + chr(t&255)
> channel.send(t) # send timestamp
> channel.close() # disconnect
> else:
> print "still waiting"
>
>Neo Chan (netkiller)
>Best Regards, 73! de BG7NYT
>Amateur Radio Callsign: BG7NYT
>
>注:我这里上不了网,请不要发URL给我,如果方便请附件发给我
>
>
>-----Original Message-----
>From: python-chinese-bounces at lists.python.cn [mailto:python-chinese-bounces at lists.python.cn] On Behalf Of Hong Yuan
>Sent: Wednesday, June 29, 2005 1:52 PM
>To: python-chinese at lists.python.cn
>Subject: [python-chinese] 如何非阻塞地读取子进程的输出
>
>我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产
>生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它
>的输出,而想先得到第一部分的输出。
>
>例如,假设外部程序是以下python代码:
>
>test.py:
>import sys, time
>print 'hello'*500
>sys.stdout.flush()
>time.sleep(100)
>print 'world'*500
>
>我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所
>有输出,即前500个'hello'。我的程序是这样写的:
>
>import os, select
>cmd = 'python test.py'
>pin, pout = os.popen2(cmd)
>select.select([pout], [], [], timeout)[0]
>pout.read()
>
>根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实
>际情况是它要一直到test.py全部执行完毕才返回可读的内容。
>
>谁知道这段代码应该如何正确书写?代码运行在Linux下。
>
>--
>HONG Yuan
>
>大管家网上建材超市
>http://www.homemaster.cn
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
>
>_______________________________________________
>python-chinese list
>python-chinese at lists.python.cn
>http://python.cn/mailman/listinfo/python-chinese
>
>
--
HONG Yuan
大管家网上建材超市
http://www.homemaster.cn
2005年06月29日 星期三 15:01
问题不在于用readline还是read,无论用哪个,都会将当前进程block到外部程序 完全执行完才会继续。 可能是对管道、缓冲什么的需要有什么设置select才能有正确的返回。 nEO wrote: >你这里不应该用read >应该用readline > >2005/6/29, Hong Yuan <hongyuan at homemaster.cn>: > > >>-- >>HONG Yuan >> >>大管家网上建材超市 >>http://www.homemaster.cn >> >>_______________________________________________ >>python-chinese list >>python-chinese at lists.python.cn >>http://python.cn/mailman/listinfo/python-chinese >> >> >> > > > > >------------------------------------------------------------------------ > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > > -- HONG Yuan 大管家网上建材超市 http://www.homemaster.cn
2005年06月29日 星期三 19:19
On 6/29/05, Hong Yuan <hongyuan at homemaster.cn> wrote: > 我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 > 生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 > 的输出,而想先得到第一部分的输出。 > > 例如,假设外部程序是以下python代码: > > test.py: > import sys, time > print 'hello'*500 > sys.stdout.flush() > time.sleep(100) > print 'world'*500 > > 我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 > 有输出,即前500个'hello'。我的程序是这样写的: > > import os, select > cmd = 'python test.py' > pin, pout = os.popen2(cmd) > select.select([pout], [], [], timeout)[0] select的作用是查看三个流的集合,发现其中的可读,可写,以及有错误报出的流。 你这里的问题,一是没有返回这个集合,所以它被当作垃圾回收了。第二select是非阻塞的,所以返回之后,它就等着执行下一句,也就是pout.read()了。这当然要等程序执行完毕才能运行。所以我觉得应该这么写: while 1 : i,o,e = select.select([pout], [], [], timeout) if i : print i[0].read() > pout.read() > > 根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 > 际情况是它要一直到test.py全部执行完毕才返回可读的内容。 > > 谁知道这段代码应该如何正确书写?代码运行在Linux下。 顺便说一句,Linux下可以,Windows下不行。Windows的select只支持socket。
2005年06月29日 星期三 19:50
你也可以继承一下StringIO,把输出重定向到这里,然后在你需要的时候抛出异常. shhgs 写道: >On 6/29/05, Hong Yuan <hongyuan at homemaster.cn> wrote: > > >>我在程序中需要启动一个外部命令并读取该命令的输出。问题是这个外部命令在产 >>生第一部分输出后要停顿很长时间,而我并不想等到外部命令全部结束再去读取它 >>的输出,而想先得到第一部分的输出。 >> >>例如,假设外部程序是以下python代码: >> >>test.py: >>import sys, time >>print 'hello'*500 >>sys.stdout.flush() >>time.sleep(100) >>print 'world'*500 >> >>我希望在自己的程序中设置一个timeout,读取外部进程在这个timeout时间前的所 >>有输出,即前500个'hello'。我的程序是这样写的: >> >>import os, select >>cmd = 'python test.py' >>pin, pout = os.popen2(cmd) >>select.select([pout], [], [], timeout)[0] >> >> > >select的作用是查看三个流的集合,发现其中的可读,可写,以及有错误报出的流。 > >你这里的问题,一是没有返回这个集合,所以它被当作垃圾回收了。第二select是非阻塞的,所以返回之后,它就等着执行下一句,也就是pout.read()了。这当然要等程序执行完毕才能运行。所以我觉得应该这么写: > >while 1 : > i,o,e = select.select([pout], [], [], timeout) > if i : > print i[0].read() > > > >>pout.read() >> >>根据文档select应该等到pout有可读取的内容(即前500个'hello')时就返回,但实 >>际情况是它要一直到test.py全部执行完毕才返回可读的内容。 >> >>谁知道这段代码应该如何正确书写?代码运行在Linux下。 >> >> > >顺便说一句,Linux下可以,Windows下不行。Windows的select只支持socket。 > > >------------------------------------------------------------------------ > >_______________________________________________ >python-chinese list >python-chinese at lists.python.cn >http://python.cn/mailman/listinfo/python-chinese > >
2005年06月30日 星期四 10:24
谢谢大家的帮助。最后下面这段代码工作得很好:
import os, fcntl, select
cmd = 'python test.py'
timeout = 2
pin, pout = os.popen2(cmd)
pout = pout.fileno()
flags = fcntl.fcntl(pout, fcntl.F_GETFL)
fcntl.fcntl(pout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
while 1:
i,o,e = select.select([pout], [], [], timeout)
if i :
buf = os.read(pout, 1024)
if buf:
print buf
else:
break
由fcntl函数将文件设为非阻塞模式,用select来判断是否有数据可读,然后用
os.read读取当前可读的所有数据。
--
HONG Yuan
大管家网上建材超市
http://www.homemaster.cn
2005年06月30日 星期四 17:54
这段代码工作正常 但是还是没明白为什么我的那段代码你不能运行 2005/6/30, Hong Yuan <hongyuan at homemaster.cn>: > > 谢谢大家的帮助。最后下面这段代码工作得很好: > > import os, fcntl, select > > cmd = 'python test.py' > > timeout = 2 > pin, pout = os.popen2(cmd) > > pout = pout.fileno() > flags = fcntl.fcntl(pout, fcntl.F_GETFL) > fcntl.fcntl(pout, fcntl.F_SETFL, flags | os.O_NONBLOCK) > > while 1: > i,o,e = select.select([pout], [], [], timeout) > if i : > buf = os.read(pout, 1024) > if buf: > print buf > else: > break > > 由fcntl函数将文件设为非阻塞模式,用select来判断是否有数据可读,然后用 > os.read读取当前可读的所有数据。 > > -- > HONG Yuan > > 大管家网上建材超市 > http://www.homemaster.cn > > _______________________________________________ > python-chinese list > python-chinese at lists.python.cn > http://python.cn/mailman/listinfo/python-chinese > -- I'm the one, powered by nEO -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.exoweb.net/pipermail/python-chinese/attachments/20050630/d82856b3/attachment.html
Zeuux © 2025
京ICP备05028076号