Python子进程在接收stdin EOF时会遇到神秘的延迟
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python子进程在接收stdin EOF时会遇到神秘的延迟,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2398字,纯文字阅读大概需要4分钟。
内容图文
![Python子进程在接收stdin EOF时会遇到神秘的延迟](/upload/InfoBanner/zyjiaocheng/955/0d7f28241f1740b58e8494013724b229.jpg)
我将我在应用程序中看到的问题减少到下面的测试用例中.在此代码中,父进程同时生成2(您可以生成更多)子进程,这些子进程通过stdin从父进程读取大消息,休眠5秒,然后回写一些内容.但是,在某处发生了意外的等待,导致代码在10秒内完成而不是预期的5.
如果设置verbose = True,则可以看到分散子进程正在接收大部分消息,然后等待3个字符的最后一个块 – 它没有检测到管道已经关闭.此外,如果我只是不对第二个过程做任何事情(doreturn = True),第一个过程将永远不会看到EOF.
有什么想法发生了什么?再往下是一些示例输出.提前致谢.
from subprocess import *
from threading import *
from time import *
from traceback import *
import sys
verbose = False
doreturn = False
msg = (20*4096+3)*'a'
def elapsed(): return '%7.3f' % (time() - start)
if sys.argv[1:]:
start = float(sys.argv[2])
if verbose:
for chunk in iter(lambda: sys.stdin.read(4096), ''):
print >> sys.stderr, '..', time(), sys.argv[1], 'read', len(chunk)
else:
sys.stdin.read()
print >> sys.stderr, elapsed(), '..', sys.argv[1], 'done reading'
sleep(5)
print msg
else:
start = time()
def go(i):
print elapsed(), i, 'starting'
p = Popen(['python','stuckproc.py',str(i), str(start)], stdin=PIPE, stdout=PIPE)
if doreturn and i == 1: return
print elapsed(), i, 'writing'
p.stdin.write(msg)
print elapsed(), i, 'closing'
p.stdin.close()
print elapsed(), i, 'reading'
p.stdout.read()
print elapsed(), i, 'done'
ts = [Thread(target=go, args=(i,)) for i in xrange(2)]
for t in ts: t.start()
for t in ts: t.join()
示例输出:
0.001 0 starting
0.003 1 starting
0.005 0 writing
0.016 1 writing
0.093 0 closing
0.093 0 reading
0.094 1 closing
0.094 1 reading
0.098 .. 1 done reading
5.103 1 done
5.108 .. 0 done reading
10.113 0 done
如果这有所不同,我正在使用Python 2.6.5.
解决方法:
经过太多时间后,我想出来了,在this post的报价跳出来之后:
See the “I/O on Pipes and FIFOs” section of pipe(7) (“man 7 pipe”)
“If all file descriptors referring to the write end of a pipe have
been closed, then an attempt to read(2) from the pipe will see
end-of-file (read(2) will return 0).”
我应该知道这一点,但我从未想过 – 特别是与Python无关.发生的事情是:子进程正在分配开放(编写器)文件描述符到彼此的管道.只要管道中有开放的编写器文件描述符,读者就不会看到EOF.
例如.:
p1=Popen(..., stdin=PIPE, ...) # creates a pipe the parent process can write to
p2=Popen(...) # inherits the writer FD - as long as p2 exists, p1 won't see EOF
原来是Popen有一个close_fds参数,所以解决方法是传递close_fds = True.事后看来,这一切都很简单明了,但仍然设法花费了至少几个眼球好时间.
内容总结
以上是互联网集市为您收集整理的Python子进程在接收stdin EOF时会遇到神秘的延迟全部内容,希望文章能够帮你解决Python子进程在接收stdin EOF时会遇到神秘的延迟所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。