使用pythontwisted框架连接多个串行套接字

发布于 2024-11-08 06:44:08 字数 923 浏览 0 评论 0原文

我目前使用twisted 连接到我拥有的串行设备,使用如下代码。

from twisted.internet import reactor
SerialPort(Handler(), "/dev/ttyACM1", reactor, baudrate='9600')
reactor.run()

但是,我知道需要扩展应用程序以监视添加(和删除)的新串行设备。我目前使用 pyinotify 来查找添加/删除的新设备,这似乎效果很好。

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        ... connect to serial device
        ...

目前我似乎有几个问题。我认为最大的问题是我对 Twisted 的了解还不够,不知道这样做的“正确”方法是什么。

目前,据我所知, pyinotify 事件处理程序在单独的线程中启动,这意味着反应器不在主线程中运行。这是一个问题吗?

连接第一个设备后,我很难添加第二个设备 - 尤其是在添加第二个设备时反应器已经在运行。即使我用

if not reactor.running: 

第二个连接来保护它,也不会正确添加到反应器中(至少connectionMade、dataReceived接收方法不会触发)。

如果我先启动反应器,然后让 pyinotify 事件尝试添加到正在运行的反应器,这似乎也不起作用 - 设备确实连接,但 dataReceived 方法永远不会被调用。

基本上,我确信有一个巧妙的方法可以让它发挥作用,但我只是无法通过谷歌或反复试验找到它。有人可以向我建议如何才能使其正常工作吗?

提前感谢您提供的任何帮助,

西蒙

I currently use twisted to connect to a serial device I have, using code like the following.

from twisted.internet import reactor
SerialPort(Handler(), "/dev/ttyACM1", reactor, baudrate='9600')
reactor.run()

However, I know need to extend the application to monitor for new serial devices being added (and removed). I currently use pyinotify to look for new devices being added/removed, and this seems to work well.

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        ... connect to serial device
        ...

At the moment I seem to have several problems. The biggest I think is that I just don't know enough about Twisted to know what the 'correct' way of doing this is.

Currently as I have it, the pyinotify event handler kicks of in a separate thread, meaning the reactor is not running in the main thread. Is this an issue?

Once the first device is connected, I struggle to add a second - not least the reactor is already running by the time the second device is added. Even if I protect that with a

if not reactor.running: 

the second connection doesn't add to the reactor properly (at least connectionMade, dataReceived received methods don't fire).

If I start the reactor first, then let the pyinotify events try and add to the running reactor this doesn't seem to work either - the device does connect, but the dataReceived method never gets called.

Basically, I'm sure there is a neat recipe for getting this to work, I just haven't been able to find it, either through Google or trial and error. Can anybody suggest to me how I might be able to get this working?

Thanks in advance for any help you're able to offer,

Simon

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

回忆躺在深渊里 2024-11-15 06:44:08

每当您想要使用 Twisted API 但您的代码未在与反应器相同的线程中运行时,您都可以使用 reactor.callFromThread 让反应器在其线程中调用您的某些代码。因此,例如,您可以执行以下操作:

def process_IN_CREATE(self, event):
    reactor.callFromThread(
        SerialPort, Handler(), "/dev/ttyACM1", reactor, baudrate='9600')

但是,您也不需要任何额外的线程来执行您所描述的操作。使用 twisted.internet.inotify 代替 pyinotify

from twisted.python.filepath import FilePath
from twisted.internet.inotify import IN_CREATE, INotify
from twisted.internet import reactor

def created(ignored, path, mask):
    SerialPort(
        Handler(),
        "/dev/ttyACM1", # Or... use `path` here?
        reactor, baudrate='9600')

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

reactor.run()

Any time you want to use a Twisted API but your code isn't running in the same thread as the reactor, you can use reactor.callFromThread to have the reactor call some of your code in its thread. So, for example, you could do something like this:

def process_IN_CREATE(self, event):
    reactor.callFromThread(
        SerialPort, Handler(), "/dev/ttyACM1", reactor, baudrate='9600')

However, you also don't need to have any extra threads to do what you described. Instead of using pyinotify, use twisted.internet.inotify:

from twisted.python.filepath import FilePath
from twisted.internet.inotify import IN_CREATE, INotify
from twisted.internet import reactor

def created(ignored, path, mask):
    SerialPort(
        Handler(),
        "/dev/ttyACM1", # Or... use `path` here?
        reactor, baudrate='9600')

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

reactor.run()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文