【问题标题】:Python hangs up on returning from a functionPython 在从函数返回时挂起
【发布时间】:2013-05-16 16:08:12
【问题描述】:

假设我在一个相当复杂的 Flask 应用程序中有两个函数。一个函数调用另一个函数。

def dispatch_unlock(...):
    # ... stuff ...
    log('dis start')
    # this routine just sends some data over a ZMQ IPC socket
    # in this scenario, the socket send will time out
    ret = acl.enqueue(unlock.id, endpoint_id, filter_entry['service_id'])
    log('dis end')
    return ret

def something_else(...);
    # ... stuff ...
    log('routecall start')
    ret = dispatch_unlock(unlock, endpoint_id, endpoint, f)
    log('routecall end')
    return ret

something_else 运行时,会产生以下输出:

routecall start
dis start
dis end

之后,它就挂断了。我尝试转储 Python 堆栈跟踪,但它们没有显示任何有用的信息。一个堆栈跟踪位于 Werkzurg 重新加载器中,另一个是通向 SIGUSR1 调用的转储程序的堆栈跟踪。

谁能建议到底发生了什么? Python 调用堆栈是否以某种方式损坏?

编辑:这是我在返回之前单步执行时pdb 显示的内容。看起来dispatch_unlock 的调用框架上方的框架不知何故丢失了。

> /SourceCache/Florence/lib/plugin/route.py(27)dispatch_unlock()
-> return ret
(Pdb) s
--Return--
> /SourceCache/Florence/lib/plugin/route.py(27)dispatch_unlock()->None
-> return ret
(Pdb) s

【问题讨论】:

  • acl.enqueue 是什么? python 在返回值时可能会挂起的一种情况是,如果函数内部调用了不能正确处理异常的 C 扩展,并且 sys.excepthook 被替换为虚假函数;但我认为情况并非如此......

标签: python flask zeromq


【解决方案1】:

这不是错误,这是一项功能

Python 在尝试垃圾收集对象并关闭由于端点不存在而未打开的 ZMQ IPC 套接字时挂断(这是正常的,因为我正在测试)。显然,在这种情况下,ZMQ 意味着无限期挂断(我花了很长时间才弄清楚,因为这在任何地方都没有记录)。这可以通过设置 ZMQ 套接字的LINGER 属性来避免,从而解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-07
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2020-03-13
    相关资源
    最近更新 更多