接着上下文
接着上文, 上次内容是说epoll timerfd的原理和函数方法,下文主要是python epoll timerfd的之间的调用.
该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.
在描述之前,我再次老生常谈关于timerfd的原理。 我们的timerfd_create()把时间变成了一个文件描述符,该文件描述符会在超时时变得可读,这种特性可以使我们在写服务器程序时,很方便的便把定时事件变成和其他I/O事件一样的处理方式,并且此定时接口的精度也足够的高,所以我们只要以后在写I/O框架时用到了定时器就该首选。
timerstack 是我新起的一个项目,就是这三个关键词python timerfd epoll ,简单说就是实现了高性能的IO定时器….
原先我用空闲时间自己用Pyobject封装timerfd的python接口,再排除问题时,搜到在google code代码库有python timerfd的模块,但问题是…. 是有问题的…. 问题主要体现在,重新赋值时settime异常, 把定时任务改成周期性任务也存在有问题… 我在上文中有聊过这个话题。 结合未写完的PyObject进行C库改造。 话说这类问题虽然很小,但真觉得是闹事 … 留坑玩呀…
项目介绍:
项目名, timerstack
项目地址, https://github.com/rfyiamcool/timerstack
timestack的安装
安装方法:
pip install timerstack
源码安装:
#xiaorui.cc git clone https://github.com/rfyiamcool/timerstack.git cd timerstack python setup.py install
函数介绍
timerstack.create(): 创建一个相对时间的定时器fd
timerstack.settime(): 设置新旧时间,可以简单理解为间隔时间和次数.
timerstack.gettime(): 查看模式
#xiaorui.cc import timerstack,os f = timerstack.create(timerfd.CLOCK_REALTIME,0) timerstack.settime(f,0,10,0) #单次 10s timerstack.settime(f,0,0,0) #停止 timerstack.settime(f,0,5,5) #每5秒钟轮一次,次数不限制 os.read(f,1024)
下面是比较完整的使用方法,另外开源的版本功能有些简单,主要是线上的调度代码虽然看起来强大,但奈何还未整理,直接塞到github中, 有失颜面呀 … 上次分享了一个关于web框架,好悬没让人喷死. 不是功能不能用,是用起来很别扭….
早已经开发好的线程池和函数映射类的功能,下个版本加入该功能.
#coding:utf-8
#xiaorui.cc
import os
import time
import logging
import select
import functools
import timerstack
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
func_map = {}
def go(*args):
logger.info(args)
def test():
for i in range(100000):
i += 10
f = timerstack.create(timerstack.CLOCK_REALTIME,0)
timerstack.settime(f,0,i,i)
func_map[f] = functools.partial(go, i)
f = timerstack.create(timerstack.CLOCK_REALTIME,0)
timerstack.settime(f,0,10,0) #only once
func_map[f] = functools.partial(go, i)
run(func_map.keys())
def run(inputs):
outputs = []
try:
# 创建 epoll 句柄
epoll_fd = select.epoll()
# 向 epoll 句柄中注册 监听 socket 的 可读 事件
for ff in inputs:
epoll_fd.register(ff, select.EPOLLIN)
except select.error, msg:
logger.error(msg)
while True:
epoll_list = epoll_fd.poll()
for fd, events in epoll_list:
func_map[fd]()
def io_select():
while inputs:
readable , writable , exceptional = select.select(inputs, outputs, inputs, 0.1)
for s in readable:
os.read(s,1024)
func_map[s](123)
if __name__ == "__main__":
test()
END.
