文件轮询变化是如何工作的?
问题
我原本以为下面的脚本最多只会打印一个事件,然后就停止(这个脚本只是为了说明问题而写的)。
#!/usr/bin/env python
from select import poll, POLLIN
filename = "test.tmp"
# make sure file exists
open(filename, "a").close()
file = open(filename, "r+")
p = poll()
p.register(file.fileno(), POLLIN)
while True:
events = p.poll(100)
for e in events:
print e
# Read data, so that the event goes away?
file.read()
但是,它每秒打印大约70000个事件。为什么会这样呢?
背景
我写了一个类,里面使用了 pyudev.Monitor 类。这个类除了其他功能外,还会使用 poll 对象 来检查通过 fileno() 方法提供的文件描述符是否有变化。
现在我想为我的类写一个单元测试(我知道应该先写单元测试,所以不需要再提醒我),因此我需要为我的模拟 pyudev.Monitor 对象写一个自己的 fileno() 方法,并且我需要控制它,以便触发 poll 对象报告一个事件。正如上面的代码所示,我无法让它停止报告那些似乎不存在的事件!
我在 poll 类中找不到 acknowledge_event() 或类似的方法来让事件消失(我怀疑只有一个事件不知怎么卡住了),在谷歌和这个网站上搜索也没有找到相关信息。我在 Ubuntu 10.10 上使用的是 python 2.6.6。
1 个回答
5
使用管道比使用文件要更有效。你可以试试这个:
#!/usr/bin/env python
import os
from select import poll, POLLIN
r_fd, w_fd = os.pipe()
p = poll()
p.register(r_fd, POLLIN)
os.write(w_fd, 'X') # Put something in the pipe so p.poll() will return
while True:
events = p.poll(100)
for e in events:
print e
os.read(r_fd, 1)
这样就能打印出你想要的那个事件。要触发轮询事件,你只需要往可写的文件描述符里写一个字节就行了。