我有一个程序,我想做两件事:
与服务器交互并响应来自服务器的事件。我正在使用twisted 来完成此操作。
为用户提供一个命令行提示符,用户可以在其中发出其他命令。到目前为止,我正在使用 python cmd 模块。
除了拥有两个线程之外似乎没有其他选择,因为 readline 只有一个阻塞接口(interface),并且需要处理自动完成之类的东西。另一方面,Twisted 必须连续运行 react 器。
现在的问题是,似乎很难用 Ctrl-C 来处理这个问题。简单的解决方案似乎是让命令行在主线程中运行,并且只使用reactor.callFromThread 来与程序的其余部分进行每次交互。这非常简单,因为覆盖 Cmd.onecmd 可以以通用方式完成此操作。但是,当我尝试在线程中生成 react 器时
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,退出 react 器,并且我被困在一个不退出的线程中,因为在 cmdloop 内调用 input()不返回。我尝试寻找解决方案以及如何退出 input() 调用,但每个人都坚持认为命令行界面应该在主线程中运行。
我发现的一个潜在选择是作为主线程运行twisted,并使输入线程成为守护进程,因此当 react 堆退出时它应该退出,但是守护进程标志没有改变任何东西(当主线程运行时线程没有退出)线程做到了)。此外,这可能很危险,因为线程被杀死时可能正在做一些重要的事情。
有什么办法可以解决这个问题吗?
最佳答案
看看如何 invective使用 Twisted 且不使用线程来执行此操作(阅读代码的一种方法可能是访问 start at the mainpoint 并按您的方式工作)。
关于python - Twisted 和命令行界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44077279/