【问题标题】:edge triggered epoll events in TwistedTwisted 中的边缘触发 epoll 事件
【发布时间】:2013-01-25 23:06:29
【问题描述】:

我正在编写这个 FileDecriptor 类(继承自 t.i.abstract.FileDescriptor)来监听 /sys 中某个文件的事件。

不幸的是,它只能与 Epoll 的边缘触发模式一起使用。所以我目前正在使用一些 hackish 解决方案来修改我在 epoll 列表中添加后的文件描述符:

self.startReading()
self._reactor._poller._control(_epoll.CTL_MOD, self.fileno(), _epoll.IN|_epoll.ET)

有没有更好的方法来做到这一点?这会带来任何问题(例如,Twisted 是否有可能在某个时候再次移除 ET 标志)?

【问题讨论】:

    标签: python twisted


    【解决方案1】:

    Twisted 很可能会再次删除此标志。正如您在示例中大量的_s 所看到的那样,您在这里使用了大量的私有 API,它们可能都会在没有警告的情况下发生变化。

    但是,没有公共界面可以做你想做的事。在我看来,如果接口要求使用特定的 sycall 接口来查询其读/写准备情况(如 epoll)而不是遵循一些适用于 epoll 的一般规则,这是一个内核错误、selectpoll 等。我的第一个倾向是针对 linux 内核提交错误。但是,如果内核人员不修复它,并且您想贡献一个带有单元测试的补丁以向 Twisted 公开此类 linux+epoll 特定事物的公共接口,请随时开票。

    【讨论】:

      【解决方案2】:

      需要注意的一个有趣的事情是,epoll 文件描述符本身是由 epoll 机制支持的。

      如果你真的需要用epoll reactor不支持的特定方式监控另一个描述符,你可以创建自己的epoll文件描述符,随意配置,然后询问epoll(或者select,或者poll,甚至 gtk) reactor 为您监控您的 epoll 文件描述符。当反应器说你的 epoll 文件描述符是可读的时,你可以对它做一个零超时的 epoll_wait 来了解它想告诉你什么。

      Twisted 已经完全支持这一点,您需要做的就是实现 IReadDescriptor 接口作为您的 epoll 文件描述符的包装器。

      【讨论】:

      • 有趣。您的意思是在我的 ReadDescriptor 中使用 epoll 对象的 fileno() 函数?我会试试的。谢谢。
      【解决方案3】:

      8 年后,这仍然是 ET EPoll 上扭曲的搜索结果的顶部,所以这是我确定的解决方案。请注意,这是“标签外”,因为它是扭曲本身的扩展。如果您破坏了它,请不要纠缠扭曲的作者寻求帮助。先上代码:

      from twisted.internet.epollreactor import EPollReactor
      from select import EPOLLET, EPOLLIN, EPOLLOUT
      
      class EPETReactor(EPollReactor):
          epflags = EPOLLIN
          def addReader(self, reader):
              try:
                  self._add(reader, self._reads, self._writes, self._selectables,
                            self.epflags, EPOLLOUT)
              except IOError as e:
                  if e.errno == errno.EPERM:
                      self._continuousPolling.addReader(reader)
                  else:
                      raise
          def startET(self):
              self.epflags = EPOLLIN | EPOLLET
          def stopET(self):
              self.epflags = EPOLLIN
      

      请注意,这仍然会涉及到twisted 的非公共API,但它可以让您在一个地方这样做,无论您需要在哪里添加ET FD。如果 twisted 的内部结构变化到足以破坏您的代码,您只需在此处修复它。此外,不会有任何事件未触发的边缘情况,因为事件在您添加 FD 和将其设置为 ET 模式之间到达。

      另外请注意,我们不会一直强制使用 ET 模式,因此您可以在切换到 ET 模式之前配置所需的任何 FD。

      用例

      如果您正在通过MSG_PEEK 从套接字读取并且只有一半的标头到达,则选择是在套接字上忙于旋转和使用边缘触发模式(或从套接字读取并弄清楚如何发送片段连同文件描述符到它的目的地,但这并不总是可能的)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-08
        • 2014-10-14
        • 2012-02-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-02
        • 2010-12-30
        相关资源
        最近更新 更多