欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2015年04月24日 10:05:32   作者:C Wong  
這篇文章主要介紹了修改Python的pyxmpp2中的主循環(huán)使其提高性能,pyxmpp2是Python中使用需XMPP協(xié)議的一個常用工具,要的朋友可以參考下

引子

之前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, 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?只需在實例化Client時傳入

mainloop = EpollMainLoop(settings)
client = Client(my_jid, [self, version_provider], settings, mainloop)

這樣就會使用epoll作為mainloop
注意

epoll僅僅在Linux下支持

相關文章

  • Python?pycryptodome庫實現(xiàn)RSA加密解密消息

    Python?pycryptodome庫實現(xiàn)RSA加密解密消息

    本文為大家介紹了如何在?Python?中使用?RSA?公鑰加密技術來加密和解密消息,并使用?pycryptodome?庫進行實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2024-02-02
  • 教你怎么用PyCharm為同一服務器配置多個python解釋器

    教你怎么用PyCharm為同一服務器配置多個python解釋器

    當我們在服務器上創(chuàng)建了多個虛擬環(huán)境時,也可以在 PyCharm 中配置這些虛擬環(huán)境,方便不同的項目使用不同的環(huán)境,然而按照網上教程添加多個python解釋器后,PyCharm會自動幫我們創(chuàng)建多個重復的服務器,本文主要給出該問題的解決方法,同時也對添加解釋器做一個詳細的講解
    2021-05-05
  • python+requests接口壓力測試500次,查看響應時間的實例

    python+requests接口壓力測試500次,查看響應時間的實例

    這篇文章主要介紹了python+requests接口壓力測試500次,查看響應時間的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python定時庫APScheduler的原理以及用法示例

    Python定時庫APScheduler的原理以及用法示例

    APScheduler的全稱是Advanced Python Scheduler,它是一個輕量級的 Python 定時任務調度框架,下面這篇文章主要給大家介紹了關于Python定時庫APScheduler的原理以及用法的相關資料,需要的朋友可以參考下
    2021-12-12
  • Python文件基本操作open函數(shù)應用與示例詳解

    Python文件基本操作open函數(shù)應用與示例詳解

    這篇文章主要為大家介紹了Python文件基本操作open函數(shù)應用與示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Python 中的pygame安裝與配置教程詳解

    Python 中的pygame安裝與配置教程詳解

    這篇文章主要介紹了Python 中的pygame安裝與配置,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • python利用winreg生成桌面路徑及實現(xiàn)掃描二維碼圖片返回相關信息

    python利用winreg生成桌面路徑及實現(xiàn)掃描二維碼圖片返回相關信息

    這篇文章主要介紹了python生成桌面路徑及實現(xiàn)掃描二維碼圖片返回相關信息,winreg是python的一個標準庫,用來對windows注冊表的操作,更多相關內容需要的小伙伴可以參考一下
    2022-06-06
  • Python虛擬環(huán)境virtualenv的安裝與使用詳解

    Python虛擬環(huán)境virtualenv的安裝與使用詳解

    virtualenv可以用來管理互不干擾的獨立python虛擬環(huán)境,在有些場景下非常有用,下面這篇文章主要給大家介紹了Python虛擬環(huán)境virtualenv安裝與使用的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05
  • 一文教你利用Python制作一個生日提醒

    一文教你利用Python制作一個生日提醒

    在國內,大部分人都是過農歷生日,然后借助日歷工具獲取農歷日期對應的陽歷日期,以這一天來過生!這里還有一個痛點,即:每一年的農歷生日對應的陽歷日期都不一樣,本篇文章將教你利用 Python 制作一個簡單的生日提醒,需要的可以參考一下
    2022-12-12
  • pyspark 隨機森林的實現(xiàn)

    pyspark 隨機森林的實現(xiàn)

    這篇文章主要介紹了pyspark 隨機森林的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04

最新評論