扭曲和命令行界面



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

  1. 与服务器交互并响应来自服务器的事件。我正在使用扭曲来做到这一点。

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

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

现在的问题是,为此处理 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

每个使用扭曲反应器的人都坚持认为扭曲反应堆应该在主螺纹中运行,因为那将是一个更好的设计。

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

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

有什么办法可以摆脱这种情况吗?

看看 Twisted 和没有线程的谩骂是如何做到的(阅读代码的一种方法可能是从主点开始并逐步进入)。

最新更新