python twisted INotify不阻塞反应器

时间:2011-06-01 11:13:43

标签: python twisted blocking inotify

我正在使用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'方法在后台运行,这样它就不会阻塞我的反应堆?

谢谢,

西蒙

2 个答案:

答案 0 :(得分:7)

Twisted中的所有事件处理程序都在“reactor thread”中运行 - UDP,TCP,并且实际上是inotify。他们都希望通过不阻塞来与系统合作。所以,在这个意义上说,这仅仅是一个有关如何写出好的事件处理程序中扭曲,不是inotify的特别问题。

有许多选项可以避免阻止。回答你的问题的棘手问题是,正确的选项取决于为什么当前的代码阻塞。

是否进行套接字I / O?请改用Twisted's non-blocking socket I/O API。

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

它是否与SQL数据库通信?也许twisted.enterprise.adbapi可以提供帮助。

等等。

我不知道这是否涵盖你所处的案例。但是,我会强调两件事。首先,在Twisted程序中使用线程是完全合理的。许多扭曲的存在,所以你不会的的使用线程,但如果你来到一个地方的情况线程完成工作,没有别的不 - 去为它(慎用)。扭曲甚至有一些帮助使其更容易,例如zeekay提到的deferToThread。其次,为任务选择合适的解决方案。所有“阻塞”问题的集合仅略微小于所有一般编程问题的集合。有很多可能的解决方案。有些人,像线程,似乎有广泛的适用性,但有一点照顾你可能会发现一个特定的情况下更多的东西特别适合。

此外,请查看Twisted: Making code non-blocking以获得进一步说明。

答案 1 :(得分:1)

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

deferToThread(self.created, ignored, path mask)