如何使用gevent来拖尾文件

时间:2012-03-18 21:25:10

标签: python gevent

构建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])

3 个答案:

答案 0 :(得分:6)

gevent 1.0b2开始,您可以使用统计观察程序获取有关文件更改的通知。

请参阅codelibev documentation for stat watchers

答案 1 :(得分:3)

嗯,那个代码没有'尾随'文件,它只是打印整个文件,但它显示'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)

答案 2 :(得分:2)

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

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])