python扭曲INotify而不阻塞反应器

Posted

技术标签:

【中文标题】python扭曲INotify而不阻塞反应器【英文标题】:python twisted INotify without blocking reactor 【发布时间】:2011-06-01 11:13:42 【问题描述】:

我正在使用 twsited 的 INotify 来监控 /dev 目录以监控正在添加的新串行设备。我目前使用的代码与下面类似。

notifier = INotify()
notifier.watch(FilePath("/dev"), IN_CREATE, callbacks=[self.created])
notifier.startReading()

def created(self, ignored, path, mask):
    ...
    blocking code
    ...

我现在遇到的问题是当“created”被调用时,它阻塞了我的反应器,所以其他网络会话(我有与同一个反应器关联的 TCP 和 UDP 连接)必须等待“created” ' 方法来完成。

有谁知道如何让“created”方法在后台运行,这样它就不会阻塞我的反应器?

谢谢,

西蒙

【问题讨论】:

【参考方案1】:

Twisted 中的所有事件处理程序都在“反应器线程”中运行 - UDP、TCP 和 inotify。他们都希望通过不阻塞来与系统合作。所以,从这个意义上说,这只是一个关于如何在 Twisted 中编写好的事件处理程序的问题,而不是具体的 inotify。

有很多选项可以避免阻塞。回答您的问题的棘手之处在于,正确的选择取决于当前代码块的确切原因。

它是否进行套接字 I/O?请改用Twisted'snon-blockingsocket I/O API。

它是否进行文件系统 I/O?您可能需要在这里use a thread,因为没有一个非阻塞文件系统 I/O 很难(也许并非不可能)。

它是否与 SQL 数据库通信?或许twisted.enterprise.adbapi 能帮上忙。

等等。

我不知道这是否涵盖了您所在的情况。但是,我将强调两点。首先,在 Twisted 程序中使用线程是完全合理的。大部分 Twisted 都存在,因此您不会必须使用线程,但如果遇到线程完成工作而没有其他工作的情况 - 去吧(谨慎;)。 Twisted 甚至有一些帮手使它变得更容易,例如 zeekay 提到的deferToThread。其次,为任务选择合适的解决方案。所有“阻塞”问题的集合仅比所有一般编程问题的集合略小。有很多可能的解决方案。有些,如线程,似乎具有广泛的适用性,但稍加注意,您可能会发现更适合特定情况的东西。

此外,请查看Twisted: Making code non-blocking 以获得更多解释。

【讨论】:

感谢您的帮助和详细的回答。我花了一些时间探索您提到的不同选项,而 deferToThread 选项似乎对我很有效。您确实提到了一些看起来很有趣的事情,那就是您建议“使用 Twisted 的非阻塞套接字 I/O API”。你能指出这些记录在哪里吗?再次感谢您的帮助。 只是像我这样的新扭曲应征者需要的详细答案。非常感谢! 有关 Twisted 的非阻塞网络 I/O API 的介绍,请参阅 twistedmatrix.com/documents/current/core/howto/servers.html 和 twistedmatrix.com/documents/current/core/howto/clients.html【参考方案2】:

您可以使用twisted.internet.threads.deferToThread 在线程中运行您的阻塞代码:

deferToThread(self.created, ignored, path mask)

【讨论】:

以上是关于python扭曲INotify而不阻塞反应器的主要内容,如果未能解决你的问题,请参考以下文章

Inotify 动态索引新文件夹

在 go-inotify 中查看递归目录

将高度变化的图像水平居中而不扭曲图像

调整图像大小而不扭曲或裁剪它

调整图像大小而不扭曲它

inotify 在删除之前还是之后触发 IN_DELETE?