1

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

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

  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作为主线程运行并使输入线程成为守护进程,因此它应该在反应器退出时退出,但是守护进程标志没有改变任何东西(当主线程退出时线程没有退出) . 此外,这可能很危险,因为线程在被杀死时可能正在做一些重要的事情。

有没有办法解决这个问题?

4

1 回答 1

1

看看invective是如何使用 Twisted 和不使用线程的(阅读代码的一种方法可能是从 mainpoint 开始并按照自己的方式工作)。

于 2017-05-20T11:47:48.997 回答