在Python中调用文件对象的readline()时暂停了

2 投票
1 回答
1199 浏览
提问于 2025-04-16 02:26

我正在使用readline()这个函数来从通过subprocess模块获得的文件对象中读取数据:proc = subprocess.Popen(cmd, bufsize=0, stdout=subprocess.PIPE)。这样我就可以把proc.stdout当作一个文件对象来用,使用proc.stdout.readline()来读取数据。我的问题是,这个操作会暂停,等待输入。如果在我调用readline的时候没有输入,我希望它能超时并继续执行。我正在使用Python 2.4,有什么办法可以让readline方法停止暂停吗?谢谢。

1 个回答

3

在一个类posix的平台上(基本上除了Windows以外的任何流行平台),select模块提供了合适的工具来完成这个任务。不过,在Windows上,select只对套接字有效(而不是管道,后者是subprocess.Popen会使用的),所以情况就不那么简单了。你需要在Windows上运行吗……?

如果不需要,那就直接在select.select调用中使用你的子进程对象pp.stdout.fileno(),并设置一个短的超时时间——这真的很简单!

编辑:这里有一个简单的例子(当然假设你已经导入了必要的模块):

>>> def f():                                                                    
...   p = subprocess.Popen("sleep 10; echo ciao", shell=True, stdout=subprocess.PIPE)
...   while True:                                                               
...     r, w, x = select.select([p.stdout.fileno()],[],[],1.0)
...     if r: return p.stdout.read()
...     print 'not ready yet'
... 
>>> f()
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
not ready yet
'ciao\n'
>>> 

请注意,没有办法“等待完整的一行”:这只是等待“任何输出”,然后会阻塞直到所有输出都准备好。要读取可用的内容,可以使用fcntl来设置文件描述符(fileno()返回的内容)上的os.O_NODELAY,然后再开始循环。

撰写回答