Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在单独的线程中启动烧瓶应用程序_Python_Multithreading_Flask - Fatal编程技术网

Python 在单独的线程中启动烧瓶应用程序

Python 在单独的线程中启动烧瓶应用程序,python,multithreading,flask,Python,Multithreading,Flask,我目前正在开发一个Python应用程序,希望在其上看到实时统计数据。我想使用Flask,以使其易于使用和理解 问题是,我的Flask服务器应该在Python应用程序的最开始启动,并在最末尾停止。应该是这样的: def main(): """ My main application """ from watcher.flask import app # watcher.flask define an app as in the Quickstart flask docume

我目前正在开发一个Python应用程序,希望在其上看到实时统计数据。我想使用
Flask
,以使其易于使用和理解

问题是,我的Flask服务器应该在Python应用程序的最开始启动,并在最末尾停止。应该是这样的:

def main():
    """ My main application """
    from watcher.flask import app
    # watcher.flask define an app as in the Quickstart flask documentation.
    # See: http://flask.pocoo.org/docs/0.10/quickstart/#quickstart

    app.run() # Starting the flask application

    do_my_stuff()

    app.stop() # Undefined, for the idea 
因为我需要我的应用程序上下文(用于统计),所以我不能使用
多处理.Process
。然后我尝试使用
线程。线程
,但看起来Werkzeug不喜欢它:

 * Running on http://0.0.0.0:10079/
Exception in thread Flask Server:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File ".../develop-eggs/watcher.flask/src/watcher/flask/__init__.py", line 14, in _run
    app.run(host=HOSTNAME, port=PORT, debug=DEBUG)
  File ".../eggs/Flask-0.10.1-py2.7.egg/flask/app.py", line 772, in run
    run_simple(host, port, self, **options)
  File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 609, in run_simple
    run_with_reloader(inner, extra_files, reloader_interval)
  File ".../eggs/Werkzeug-0.7-py2.7.egg/werkzeug/serving.py", line 524, in run_with_reloader
    signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
ValueError: signal only works in main thread
如何在主线程中不运行烧瓶的情况下执行此操作?

来自:

正在关闭服务器

版本0.7中的新功能

从Werkzeug 0.7开始,开发服务器提供了一种 请求后关闭服务器。这目前只适用于 Python2.6及更高版本,并且只与开发服务器一起使用。 要启动关机,必须调用名为 WSGI环境中的“werkzeug.server.shutdown”:

def shutdown_server(environ):
    if not 'werkzeug.server.shutdown' in environ:
        raise RuntimeError('Not running the development server')
    environ['werkzeug.server.shutdown']()

您正在调试模式下运行
Flask
,这将启用重新加载程序(代码更改时重新加载Flask服务器)

Flask可以在单独的线程中正常运行,但重载程序希望在主线程中运行


要解决您的问题,您应该禁用调试(
app.debug=False
),或者禁用重新加载程序(
app.use_reloader=False


这些也可以作为参数传递给
app.run
app.run(debug=True,使用_reloader=False)
,如果您要访问Flask中的iPython终端 在单独的线程中运行应用程序。试试这个例子:

from flask import Flask                                                         
import thread

data = 'foo'
app = Flask(__name__)

@app.route("/")
def main():
    return data

def flaskThread():
    app.run()

if __name__ == "__main__":
    thread.start_new_thread(flaskThread, ())

(在iPython中运行此文件)

更新了Python 3的答案,它更简单一些:

from flask import Flask                                                         
import threading

data = 'foo'
app = Flask(__name__)

@app.route("/")
def main():
    return data

if __name__ == "__main__":
    threading.Thread(target=app.run).start()

我已经在一个单独的线程中运行了Flask应用程序,所以您看到的这个错误是令人惊讶的。你有完整的回溯吗?完整的回溯添加了你以某种方式设置的
app.debug=True
?是的。如果我正在线程化,它就不能设置为True?你能显示在单独线程中运行flask的代码吗?我不知道你的答案。据我所知,这是一种停止服务器的方法,但我的问题不仅仅是如何停止服务器,还包括如何启动服务器。你能补充一个小例子吗?谢谢你的回答。能否添加一个关于如何在单独线程中正确关闭服务器的代码示例/文档链接?@FunkySayu通常会创建一个
/shutdown
路由。路由代码是:
flask.request.environ.get('werkzeug.server.shutdown')()
。要关闭服务器,只需向
/shutdown
发出HTTP请求。为了安全起见,您通常会添加一个只有您的应用程序知道的令牌,这样其他人就无法关闭服务器(您可以调用
/shutdown?token=somethingSecret
)好的,这就是下面的答案。现在我明白了。谢谢您的帮助。但是在代码更改时重新加载服务器很有用,我可以同时使用它们吗?然后如何停止?可能需要将导入语句修复为
导入线程
。无法进行编辑,因为更改>6个字符需要进行编辑。如果我需要在app.run中传递一个选项,该怎么办?像app.run(host='0.0.0.0')一样,我尝试过这样做,但是线程failed@AmanKejriwal使用一个单独的函数,使用所需的参数运行app.run,并在线程内调用该函数。你有例子吗?@AmanKejriwal