【问题标题】:Twisted reactor is stopped, but program doesn't end?Twisted reactor 停止,但程序没有结束?
【发布时间】:2012-11-20 21:33:22
【问题描述】:

所以我正在编写一个与 Deluge 一起使用的小脚本。 Deluge 使用 Twisted,我真的不知道它是如何工作的。通常我只是查找有关它的更多信息,但开始使用 Twisted 需要 很长 时间,并且超出了这个小项目的范围。所以我想我会在这里问。

现在,我有这个代码。我将尝试解释我需要帮助的具体部分

import base64

import processargs

from deluge.ui.client import client
from twisted.internet import reactor

from deluge.log import setupLogger
setupLogger()

options = processargs.readConfig(os.path.expanduser("~/.deluge-automator"))

d = client.connect(
    host=options['host'],
    port=int(options['port']),
    username=options['username'],
    password=options['password']
)

def start():
    #other code

    t = client.core.add_torrent_file(tfile,
                                     base64.encodestring(data), None)

    t.addCallback(on_torrent_added_success, tfile)
    t.addErrback(on_torrent_added_fail)


def handle_stop_signal(SIGNAL, stack):
    client.disconnect()
    reactor.stop()


def on_torrent_added_success(result, tfile):
    #other code
    start()


def on_torrent_added_fail(result):
    print "Add torrent failed!"
    print "result: ", result


def on_connect_success(result):
    #other code
    start()


d.addCallback(on_connect_success)


def on_connect_fail(result):
    print "Connection failed!"
    print "result: ", result


d.addErrback(on_connect_fail)

signal.signal(signal.SIGTERM, handle_stop_signal)
signal.signal(signal.SIGINT, handle_stop_signal)

reactor.run()

成功添加种子后,它应该返回到 start(),它确实如此,但我认为它会丢失反应器或其他东西。因为现在只要收到 SIGTERM 或 SIGINT,reactor 就会关闭,但不会退出程序:

± % python2 main.py
Connection was successful!
result:  10
^C^CConnection failed!
result:  [Failure instance: Traceback: <class 'twisted.internet.error.ReactorNotRunning'>: Can't stop reactor that isn't running.
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks
/usr/lib/python2.7/site-packages/deluge/ui/client.py:412:__on_login
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:368:callback
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:464:_startRunCallbacks
--- <exception caught here> ---
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks
main.py:70:on_connect_success
main.py:32:start
main.py:49:handle_stop_signal
/usr/lib/python2.7/site-packages/twisted/internet/base.py:577:stop
]

所以反应器停止了,但它并没有退出程序。我必须两次键盘中断。一次停止反应器,第二次抛出错误。有没有某种方法可以设置这样的循环?

【问题讨论】:

    标签: python twisted


    【解决方案1】:

    reactor 处理 sigint,sigterm 本身(可能有一个 reactor.run() 的参数禁用它)。改为安装reactor.addSystemEventTrigger('before', 'shutdown', client.disconnect)

    twisted: catch keyboardinterrupt and shutdown properly

    【讨论】:

    • 只是想补充一点,在信号处理程序中调用 Twisted API 是不安全的。信号处理程序是一种抢占式上下文切换,它们与线程一样不安全,必须小心处理。只有标记为线程安全的 Twisted API 可以在信号处理程序中使用(其中最有趣的是 reactor.callFromThread)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多