1

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

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

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

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

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

谢谢,

西蒙

4

2 回答 2

7

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

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

它做套接字 I/O 吗?请改用Twisted 的 非阻塞 套接字 I/O API。

它是否执行文件系统 I/O?您可能需要在这里使用一个线程,因为没有一个非阻塞文件系统 I/O 是困难的(也许并非不可能)。

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

等等。

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

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

于 2011-06-01T12:11:40.223 回答
1

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

deferToThread(self.created, ignored, path mask)
于 2011-06-01T12:09:10.817 回答