常春岛资源网 Design By www.syssdc.com
引子
之前clubot使用的pyxmpp2的默认mainloop也就是一个poll的主循环,但是clubot上线后资源占用非常厉害,使用strace跟踪发现clubot在不停的poll,查看pyxmpp2代码发现pyxmpp2的poll在使用超时阻塞时使用最小超时时间,而最小超时时间一直是0,所以会变成一个没有超时的非阻塞poll很浪费资源,不打算更改库代码,所以自己仿照poll的mainloop写了一个更加高效的epoll的mainloop
实现
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Author : cold
# E-mail : wh_linux@126.com
# Date : 13/01/06 10:41:31
# Desc : Clubot epoll mainloop
#
from __future__ import absolute_import, division
import select
from pyxmpp2.mainloop.interfaces import HandlerReady, PrepareAgain
from pyxmpp2.mainloop.base import MainLoopBase
from plugin.util import get_logger
class EpollMainLoop(MainLoopBase):
""" Main event loop based on the epoll() syscall on Linux system """
READ_ONLY = (select.EPOLLIN | select.EPOLLPRI | select.EPOLLHUP |
select.EPOLLERR |select.EPOLLET)
READ_WRITE = READ_ONLY | select.EPOLLOUT
def __init__(self, settings = None, handlers= None):
self.epoll = select.epoll()
self._handlers = {}
self._unprepared_handlers = {}
self._timeout = None
self._exists_fd = {}
self.logger = get_logger()
MainLoopBase.__init__(self, settings, handlers)
return
def _add_io_handler(self, handler):
self._unprepared_handlers[handler] = None
self._configure_io_handler(handler)
def _configure_io_handler(self, handler):
if self.check_events():
return
if handler in self._unprepared_handlers:
old_fileno = self._unprepared_handlers[handler]
prepared = self._prepare_io_handler(handler)
else:
old_fileno = None
prepared = True
fileno = handler.fileno()
if old_fileno is not None and fileno != old_fileno:
del self._handlers[old_fileno]
self._exists.pop(old_fileno, None)
self.epoll.unregister(old_fileno)
if not prepared:
self._unprepared_handlers[handler] = fileno
if not fileno:
return
self._handlers[fileno] = handler
events = 0
if handler.is_readable():
events |= self.READ_ONLY
if handler.is_writable():
events |= self.READ_WRITE
if events:
if fileno in self._exists_fd:
self.epoll.modify(fileno, events)
else:
self._exists_fd.update({fileno:1})
self.epoll.register(fileno, events)
def _prepare_io_handler(self, handler):
ret = handler.prepare()
if isinstance(ret, HandlerReady):
del self._unprepared_handlers[handler]
prepared = True
elif isinstance(ret, PrepareAgain):
if ret.timeout is not None:
if self._timeout is not None:
self._timeout = min(self._timeout, ret.timeout)
else:
self._timeout = ret.timeout
prepared = False
else:
raise TypeError("Unexpected result from prepare()")
return prepared
def _remove_io_handler(self, handler):
if handler in self._unprepared_handlers:
old_fileno = self._unprepared_handlers[handler]
del self._unprepared_handlers[handler]
else:
old_fileno = handler.fileno()
if old_fileno is not None:
try:
del self._handlers[old_fileno]
self._exists.pop(old_fileno, None)
self.epoll.unregister(old_fileno)
except KeyError:
pass
def loop_iteration(self, timeout = 60):
next_timeout, sources_handled = self._call_timeout_handlers()
if self.check_events():
return
if self._quit:
return sources_handled
for handler in list(self._unprepared_handlers):
self._configure_io_handler(handler)
if self._timeout is not None:
timeout = min(timeout, self._timeout)
if next_timeout is not None:
timeout = min(next_timeout, timeout)
if timeout == 0:
timeout += 1 # 带有超时的非阻塞,解约资源
events = self.epoll.poll(timeout)
for fd, flag in events:
if flag & (select.EPOLLIN | select.EPOLLPRI | select.EPOLLET):
self._handlers[fd].handle_read()
if flag & (select.EPOLLOUT|select.EPOLLET):
self._handlers[fd].handle_write()
if flag & (select.EPOLLERR | select.EPOLLET):
self._handlers[fd].handle_err()
if flag & (select.EPOLLHUP | select.EPOLLET):
self._handlers[fd].handle_hup()
#if flag & select.EPOLLNVAL:
#self._handlers[fd].handle_nval()
sources_handled += 1
self._configure_io_handler(self._handlers[fd])
return sources_handled
使用
如何使用新的mainloop"htmlcode">
mainloop = EpollMainLoop(settings) client = Client(my_jid, [self, version_provider], settings, mainloop)
这样就会使用epoll作为mainloop
注意
epoll仅仅在Linux下支持
标签:
Python
常春岛资源网 Design By www.syssdc.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
常春岛资源网 Design By www.syssdc.com
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2025年10月28日
2025年10月28日
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]