国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

修改Python的pyxmpp2中的主循環(huán)使其提高性能

2020-02-23 00:51:41
字體:
供稿:網(wǎng)友

引子

之前clubot使用的pyxmpp2的默認mainloop也就是一個poll的主循環(huán),但是clubot上線后資源占用非常厲害,使用strace跟蹤發(fā)現(xiàn)clubot在不停的poll,查看pyxmpp2代碼發(fā)現(xiàn)pyxmpp2的poll在使用超時阻塞時使用最小超時時間,而最小超時時間一直是0,所以會變成一個沒有超時的非阻塞poll很浪費資源,不打算更改庫代碼,所以自己仿照poll的mainloop寫了一個更加高效的epoll的mainloop
實現(xiàn)

#!/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, divisionimport selectfrom pyxmpp2.mainloop.interfaces import HandlerReady, PrepareAgainfrom pyxmpp2.mainloop.base import MainLoopBasefrom plugin.util import get_loggerclass 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            
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 汤原县| 晋中市| 波密县| 佳木斯市| 蓬莱市| 虞城县| 安塞县| 安图县| 仁怀市| 馆陶县| 南靖县| 夏津县| 徐汇区| 哈巴河县| 丹棱县| 淅川县| 南投县| 定安县| 洪雅县| 塔河县| 赫章县| 新竹县| 基隆市| 嘉兴市| 浮梁县| 沙洋县| 临朐县| 庆元县| 六安市| 无棣县| 永平县| 个旧市| 古田县| 涿州市| 北流市| 湖口县| 开封县| 铜鼓县| 开封县| 衢州市| 宁明县|