繁体   English   中英

从正在用Python写入的打开文件句柄中读取

[英]Reading from open file handle that is being written to in Python

我知道这是流处理中的经典问题,但是我不知道如何在Python中处理它。 我有一个活动进程正在写入的文件句柄。 我想逐行使用该文件句柄中的内容,但是我不想死锁等待读取。 我将继续阅读直到EOF或循环阅读60秒(以先到者为准)。 有关如何执行此操作的建议将不胜感激。 我对此问题的伪代码描述如下。

proc = genprocess("command")
found_a = False
found_b = False
start = time.time()
while True:
    line = proc.readline()
    while line:
        if not found_a and grep(pattern_a, line):
            found_a = True
            print "Found A, now looking for B"
        elif not found_b and grep(pattern_b, line):
            found_b = True
            print "Found B, all done"
            break
    if time.time() - start > 60:
        break
    else:
        time.sleep(5)

proc.kill()

问题在于,每个间隔只能读取一行。 相反,我希望循环的内部尽可能多地进行迭代,但不要阻止等待新内容写入文件的等待。 一旦读取了足够多的内容,它应该休眠5秒钟以允许更多内容积累。

如果您在Unix环境上运行,则可以使用Python的select模块来等待文件句柄上的数据。 另外,您可以使用Python的fcntl模块将文件句柄更改为非阻塞模式,如本问题所述

例如,假设您的proc变量是支持fileno()的常规文件句柄:

file_num = proc.fileno()
old_flags = fcntl.fcntl(file_num, fcntl.F_GETFL)
fcntl.fcntl(file_num, fcntl.F_SETFL, old_flags | os.O_NONBLOCK)

上面链接的fcntl示例是可以的(除了它将进程置于繁忙循环轮询中),但是我最终使用“ select”来实现或多或少的所需功能。

    started = False
    while True:
        if (time.time() - start > wait_for) or started:
            break
        (rlist, wlist, xlist) = select([proc.stdout], [], [], wait_interval)
        if len(rlist) > 0:
            line = rlist[0].readline() # read one line (this blocks until '\n' is read)
        else: # nothing available to read from proc.stdout
            print ".",
            sys.stdout.flush()
            time.sleep(1)
            continue
        if re.search("daemon started", line):
            started = True

    if not started:
        proc.kill() # don't leave the process running if it didn't start properly

如果这是用户可能会按CTRL-C进行的操作,则将整个操作放在try / except块中并查找KeyboardInterrupt允许调用proc.kill()而不是使进程在后台运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM