基于timerfd epoll开发的io定时器 [下]

接着上下文

接着上文, 上次内容是说epoll timerfd的原理和函数方法,下文主要是python epoll timerfd的之间的调用.

该文章写的有些乱,欢迎来喷 ! 另外文章后续不断更新中,请到原文地址查看更新.

http://xiaorui.cc/?p=3693


在描述之前,我再次老生常谈关于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.



大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

发表评论

邮箱地址不会被公开。 必填项已用*标注