【问题标题】:How to tail a file with gevent如何使用 gevent 尾随文件
【发布时间】:2012-03-18 21:25:10
【问题描述】:

我在构建 gevent 尾函数时遇到问题。一般来说,当我在循环中注释 gevent.sleep 时,代码可以工作,但是 CPU 利用率是 100%。当我离开 gevent.sleep 程序工作但没有发生任何事情。 Gevent版本是1.0b1。

import os
import gevent

def follow(filename):
    fd = os.open(filename, os.O_RDONLY|os.O_NONBLOCK)
    os.lseek(fd, 0, os.SEEK_END)
    hub = gevent.get_hub()
    watcher = hub.loop.io(fd, 1)
    while True:
        hub.wait(watcher)
        lines = os.read(fd, 4096).splitlines()
        if not lines:
            #gevent.sleep(.1)
            continue
        else:
            for line in lines:
                print "%s:%s" % (filename, line)

    os.close(fd)

if __name__ == '__main__':
    job1 = gevent.spawn(follow, '/var/log/syslog')
    job2 = gevent.spawn(follow, '/var/log/messages')

    gevent.joinall([job1, job2])

【问题讨论】:

  • 如果您找到了答案,请将其作为答案发布(并尽可能接受)

标签: python gevent


【解决方案1】:

gevent 1.0b2 开始,您可以使用 stat watchers 来获取有关文件更改的通知。

请参阅 codelibev documentation for stat watchers

【讨论】:

    【解决方案2】:

    好吧,那是代码不会“拖尾”文件,它只是打印整个文件,但它显示了“loop.stat”的工作原理。它等待文件更改 - 或者只是被触摸,然后打印内容。等待时 - 几乎不需要任何资源!

    import gevent,os
    
    def follow(filename):
        hub = gevent.get_hub()
        watcher = hub.loop.stat(filename)
        while True:
            hub.wait(watcher)
            with open(filename) as f:
                print f.read()
    
    if __name__ == '__main__':
        jobs=[gevent.spawn(follow,'/var/log/syslog')]
        jobs+=[gevent.spawn(follow,'/var/log/messages')]
        gevent.joinall(jobs)
    

    【讨论】:

    • +1:谢谢 Josh,这几乎正是我所需要的。我有一个 ZeroRPC 服务器(使用 Gevent),我需要监视整个目录中的新文件和对现有文件的修改。我的谷歌搜索失败了,你能给我任何指针/代码片段吗:)
    【解决方案3】:

    显然是错误的方法。这非常有效:

    import os
    import gevent
    
    def follow(filename):
        fd = os.open(filename, os.O_RDONLY|os.O_NONBLOCK)
        os.lseek(fd, 0, os.SEEK_END)
        while True:
            lines = os.read(fd, 4096).splitlines()
            if not lines:
                gevent.sleep(.5)
                continue
            else:
                for line in lines:
                    print "%s:%s" % (filename, line)
    
        os.close(fd)
    
    if __name__ == '__main__':
        job1 = gevent.spawn(follow, '/var/log/syslog')
        job2 = gevent.spawn(follow, '/var/log/messages')
    
        gevent.joinall([job1, job2])
    

    【讨论】:

    • 旁注:如果输入队列中有超过 4096 个字节在等待,那么这将在所有第 4096 个字节后自动换行。
    猜你喜欢
    • 2016-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-02
    • 2019-08-04
    • 1970-01-01
    • 2022-11-21
    相关资源
    最近更新 更多