我有一个程序,我想做两件事:
与服务器交互并响应来自服务器的事件。我正在使用扭曲做这个。
为用户提供命令行提示,他可以在其中发出其他命令。到目前为止,我正在为此使用 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作为主线程运行并使输入线程成为守护进程,因此它应该在反应器退出时退出,但是守护进程标志没有改变任何东西(当主线程退出时线程没有退出) . 此外,这可能很危险,因为线程在被杀死时可能正在做一些重要的事情。
有没有办法解决这个问题?