首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Quart无法关闭后台任务

Python Quart无法关闭后台任务
EN

Stack Overflow用户
提问于 2021-01-07 04:36:00
回答 1查看 329关注 0票数 1

我正在开发一个Python应用程序,但我正在从Flask移动到Quart。应用程序需要一个在应用程序运行时持续运行的后台任务。

当我尝试使用control-c停止该进程时,线程并没有干净地关闭,而是处于shutdown例程中的while循环中。

代码语言:javascript
复制
    while not self._master_thread_class.shutdown_completed:
        if not pro:
            print('[DEBUG] Thread is not complete')
            pro = True

我已经跟踪了this堆栈溢出问题,但我不知道如何干净利落地关闭后台线程,所以我想要一个解释,因为它看起来夸特文档有点缺乏。

MasterThread类:

代码语言:javascript
复制
import asyncio

class MasterThread:

    def __init__(self, shutdown_requested_event):
        self._shutdown_completed = False
        self._shutdown_requested_event = shutdown_requested_event
        self._shutdown_requested = False

    def __del__(self):
        print('Thread was deleted')

    def run(self, loop) -> None:
        asyncio.set_event_loop(loop)
        loop.run_until_complete(self._async_entrypoint())

    @asyncio.coroutine
    def _async_entrypoint(self) -> None:
        while not self. _shutdown_requested and \
            not self._shutdown_requested_event.isSet():
            #print('_main_loop()')
            pass

            if self._shutdown_requested_event.wait(0.1):
                self. _shutdown_requested = True

        print('[DEBUG] thread has completed....')
        self._shutdown_completed = True

    def _main_loop(self) -> None:
        print('_main_loop()')

主要应用模块:

代码语言:javascript
复制
import asyncio
import threading
from quart import Quart
from workthr import MasterThread

app = Quart(__name__)

class Service:

    def __init__(self):
        self._shutdown_thread_event = threading.Event()
        self._master_thread = MasterThread(self._shutdown_thread_event)
        self._thread = None

    def __del__(self):
        self.stop()

    def start(self):
        loop = asyncio.get_event_loop()
        self._thread = threading.Thread(target=self._master_thread.run, args=(loop,))
        self._thread.start()
        return True

    def stop(self) -> None:
        print('[DEBUG] Stop signal caught...')
        self._shutdown_thread_event.set()
        while not self._master_thread.shutdown_completed:
            print('[DEBUG] Thread is not complete')

        print('[DEBUG] Thread has completed')

        self._shutdown()

    def _shutdown(self):
        print('Shutting down...')

service = Service()
service.start()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-08 02:03:37

Quart有一些startup and shutdown方法,允许在服务器开始服务之前启动一些东西,并在服务器结束服务时停止。如果你的后台任务主要是IO限制的,我建议你只使用协程函数而不是线程,

代码语言:javascript
复制
async def background_task():
    while True:
        ...

@app.before_serving
async def startup():
    app.background_task = asyncio.ensure_future(background_task())

@app.after_serving
async def shutdown():
    app.background_task.cancel()  # Or use a variable in the while loop

或者您也可以对您的服务执行相同的操作,

代码语言:javascript
复制
@app.before_serving
async def startup():
    service.start()

@app.after_serving
async def shutdown():
    service.stop()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65603039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档