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