【问题标题】:Twisted and a command line interfaceTwisted 和命令行界面
【发布时间】:2017-05-19 19:02:09
【问题描述】:

我有一个程序,我想做两件事:

  1. 与服务器交互并响应来自服务器的事件。我正在使用twisted 进行此操作。

  2. 为用户提供命令行提示符,用户可以在其中发出其他命令。到目前为止,我正在使用 python cmd 模块。

似乎除了拥有两个线程之外别无选择,因为 readline 只有一个阻塞接口,需要处理诸如自动完成之类的事情。另一方面,Twisted 必须连续运行反应堆。

现在的问题是,为此处理 Ctrl-C 似乎非常困难。简单的解决方案似乎是让命令行在主线程中运行,并且只使用 reactor.callFromThread 与程序的其余部分进行每次交互。这非常容易,因为覆盖 Cmd.onecmd 可以以通用方式执行此操作。但是,当我尝试在线程中生成反应器时,

t = Thread(target=reactor.run)
t.start()

我立即得到一个异常

File "/usr/lib/python3.6/signal.py", line 47, in signal
    handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
builtins.ValueError: signal only works in main thread

每个使用twisted的人都坚持twisted reactor应该在主线程中运行,因为这样会更好。

当尝试这样做并在主线程中扭曲运行时,它将捕获 Ctrl-C,退出反应器,我被一个不退出的线程卡住,因为在 cmdloop 中调用 input()不返回。我尝试寻找解决方案以及如何摆脱 input() 调用,但每个人都坚持命令行界面应该在主线程中运行。

我发现的一个可能的选择是将twisted作为主线程运行并使输入线程成为守护进程,因此它应该在反应器退出时退出,但是守护进程标志没有改变任何东西(主线程时线程没有退出线程做了)。此外,这可能很危险,因为线程在被杀死时可能正在做一些重要的事情。

有什么办法可以解决吗?

【问题讨论】:

  • Twisted examples 页面上有一个名为 stdiodemo.py 的示例,这应该是一个很好的起点。这个例子展示了如何在没有线程的情况下做你想做的事情。

标签: python twisted python-multithreading python-cmd


【解决方案1】:

看看invective 是如何使用 Twisted 和没有线程的(阅读代码的一种方法可能是到 start at the mainpoint 并按照自己的方式工作)。

【讨论】:

    猜你喜欢
    • 2021-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    • 2012-11-19
    • 1970-01-01
    相关资源
    最近更新 更多