簡體   English   中英

Python Quart 無法關閉后台任務

[英]Python Quart Unable to shutdown background task

我正在開發 Python 應用程序,但我正在從 Flask 轉移到 Quart。 應用程序需要一個在應用程序運行時不斷運行的后台任務。

當我嘗試使用 control-c 停止進程時,線程不會干凈地關閉並位於關閉例程的 while 循環中。

    while not self._master_thread_class.shutdown_completed:
        if not pro:
            print('[DEBUG] Thread is not complete')
            pro = True

我已經關注了這個Stackoverflow 問題,但我不知道如何干凈地關閉后台線程,所以我希望得到一個解釋,因為 Quart 文檔似乎缺少一點。

MasterThread class:

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()')

主要應用模塊:

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()

Quart 具有啟動和關閉方法,允許在服務器開始服務之前啟動某些東西,並在服務器完成服務時停止。 如果您的后台任務主要是 IO 綁定我建議只使用協程 function 而不是線程,

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

或者你可以對你的服務做同樣的事情,

@app.before_serving
async def startup():
    service.start()

@app.after_serving
async def shutdown():
    service.stop()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM