5

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

3 回答 3

6

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

请参阅 stat watchers 的代码libev 文档

于 2012-03-23T06:30:29.430 回答
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)
于 2012-11-07T10:10:38.573 回答
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])
于 2012-03-19T07:33:14.503 回答