【问题标题】:Non-blocking server in TwistedTwisted 中的非阻塞服务器
【发布时间】:2012-10-16 15:18:22
【问题描述】:

我正在构建一个需要在主线程以外的线程上运行 TCP 服务器的应用程序。尝试运行以下代码时:

reactor.listenTCP(ServerConfiguration.tcpport, TcpCommandFactory())
reactor.run()

我收到以下错误

exceptions.ValueError: 信号只在主线程中起作用

我可以在主线程以外的线程上运行扭曲服务器吗?

【问题讨论】:

  • Twisted 本质上是非阻塞的。见*.com/questions/4263059/…
  • 从我进行的测试来看,它确实阻塞了主线程,如果你在“reactor.run()”命令之前和之后放置一个打印消息,你会看到后面的消息永远不会打印。
  • reactor.run() 运行扭曲直到扭曲完成并关闭,然后在 reactor.run 之后的代码将运行。您可以将您的代码与扭曲的函数/回调集成,从而实现非阻塞。我选择放弃扭曲并使用 gevent 处理大多数事情。我听说 zeroMQ 也很棒。
  • 如果您不熟悉异步编程,twisted tutorial 可能会有所帮助
  • 您能解释一下为什么您决定需要线程吗? Twisted 中可能有一个 API 可以帮助您在没有线程的情况下实现目标。

标签: python twisted


【解决方案1】:

Twisted 可以在任何线程中运行 - 但一次只能在一个线程中运行。如果你想在非主线程中运行,只需执行reactor.run(installSignalHandlers=False)。但是,您不能在非主线程上使用反应器来生成子进程,因为它们的终止永远不会被检测到。 (这是 UNIX 的限制,真的,不是 Twisted。)

【讨论】:

  • 非常感谢,我之前没有找到这个,但是 Twisted FAQ 有一个关于这个主题的条目! twistedmatrix.com/trac/wiki/…
  • 你拯救了我的一天,先生
  • 很高兴我们能帮上忙!
  • @Glyph 有没有办法在react的范围内使用它
  • 否; react 旨在为您的程序的主要点提供合理的默认值。如果您想自己使用自定义标志仔细管理反应器,则需要自己致电 reactor.run 并管理其生命周期。