【问题标题】:Why is pickle crashing my flask server?为什么泡菜会使我的烧瓶服务器崩溃?
【发布时间】:2014-01-28 19:48:17
【问题描述】:

问题

我正在运行一个服务器,当我尝试腌制一个简单的、可腌制的对象时,它会崩溃。仅当打开调试模式时服务器才会崩溃。如果我删除debug=True,服务器运行正常。当我将代码放入单个文件而不是包中时,我也无法复制该错误。 Python 2.7 和 3.3 都出现了这个问题。

在收到“/”路径的获取请求后服务器崩溃。我没有得到任何关于出了什么问题或发生了什么的反馈 - 浏览器页面就像正在加载一样永远挂起。使用调试器运行程序没有帮助。

我怀疑由于烧瓶自动重新加载模块的方式,pickle 无法定位基类文件,但我不知道如何进一步探索这个想法。

代码

我有一个结构如下的包:

MyServer
    __init__.py
runserver.py

__init__.py:

import pickle
import flask

app = flask.Flask(__name__)

class Test(object):
    def __init__(self, name):
        self.name = name

@app.route('/')
def show_front():
    o = Test('test')
    x = pickle.dumps(o)
    return x

app.run(debug=True)

运行服务器.py:

import MyServer

【问题讨论】:

  • 当你说它“崩溃”时,它会给你回溯吗?你能识别出错误消息或行号吗?
  • 没有回溯。如果我尝试在浏览器中加载页面,浏览器就会挂在那里。当我尝试使用调试器单步执行时,进程就像在等待某事一样停止,但我不知道是什么。

标签: python flask pickle


【解决方案1】:

我使用hanging_threads 来获取线程正在等待的位置。 这是众多行中的一行:

  File "C:\Python27\lib\subprocess.py", line 997, in wait
    _subprocess.INFINITE)

Flask 启动了一个新进程,该进程等待并提供我猜想的输出。 但如果它启动一个新进程,则意味着:

app.run(debug=True)

也在子进程中执行。

解决方案:

  1. 如果已导入,请不要启动应用程序。 app.run(debug=True) =>

    if __name__ == '__main__': app.run(debug=True)
    
  2. runserver.py 更改为

    import MyServer
    MyServer.app.run(debug=True)
    

然后我得到了这个输出:

ccopy_reg _reconstructor p0 (cMyServer Test p1 c__builtin__ object p2 Ntp3 Rp4 (dp5 S'name' p6 S'test' p7 sb.

【讨论】:

  • 我按照您的建议更改了 runserver.py,它似乎已经解决了问题。令人惊讶的是,除了泡菜之外,一切似乎都运行良好。你知道为什么 pickle 会导致线程挂起吗?
  • 第一个我知道pickle使用__import__为一个类加载一个模块。第二个烧瓶使用子进程/多进程。但我不知道,只能猜测 pickle 可能不止一次加载模块?
猜你喜欢
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
相关资源
最近更新 更多