And*_*kia 5 python event-loop multiprocessing class-variables fastapi
我在 FastAPI 应用程序中有以下类:
import asyncio
import logging
from multiprocessing import Lock, Process
from .production_status import Job as ProductionStatusJob
class JobScheduler:
loop = None
logger = logging.getLogger("job_scheduler")
process_lock = Lock()
JOBS = [ProductionStatusJob]
@classmethod
def start(cls) -> None:
cls.logger.info("Starting Up (1/2)")
Process(target=cls._loop).start()
@classmethod
def _loop(cls) -> None:
cls.loop = asyncio.get_event_loop()
cls.loop.create_task(cls._run())
cls.logger.info("Startup Complete (2/2)")
cls.loop.run_forever()
cls.loop.close()
@classmethod
async def _run(cls) -> None:
while True:
...
@classmethod
async def stop(cls) -> None:
cls.logger.info("Shutting Down (1/2)")
with cls.process_lock:
cls.loop.stop() # <= This Line
cls.loop.close()
cls.logger.info("Shutdown Complete (2/2)")
cls.loop = None
Run Code Online (Sandbox Code Playgroud)
在FastAPI 应用程序的startup和事件上,将调用和方法。shutdownJobScheduler.start()JobScheduler.stop()
该start方法运行顺利,但stop出现错误:
File "/backend/app/main.py", line 146, in stop_job_scheduler
2023-08-16 11:46:27 await job_scheduler.stop()
2023-08-16 11:46:27 File "/backend/app/jobs/__init__.py", line 59, in stop
2023-08-16 11:46:27 cls.loop.stop()
2023-08-16 11:46:27 AttributeError: 'NoneType' object has no attribute 'stop'
Run Code Online (Sandbox Code Playgroud)
但是cls.loop是在_loop方法期间设置的(在方法结束时执行start)——那么为什么在调用方法时cls.loop仍然有其初始None值呢?stop
当 FastAPI 应用程序调用时,是否有更好的方法来清理后台进程shutdown?
multiprocessing在Python中很有趣。它比多线程更强大,但也有一些注意事项。首先,您实际上正在运行一个完全不同的 Python 解释器。这意味着全局变量等将为您运行的每个进程获取一个新副本。
根据您的操作系统和启动方法的选择,您的进程可能会被分叉或派生。生成的进程将重新开始,就像一个新的 Python 程序刚刚启动一样。分叉进程将从源进程获取变量的所有当前值,但它仍然会复制所有这些变量。如果不使用其中一个帮助程序进行显式同步,未来对任一进程的更改都不会影响另一个进程multiprocessing。
您可以使用 aManager来显式同步进程之间的数据。这有点像两个进程都连接到的本地服务器。对于更明确的发布-订阅数据,您还可以使用 aQueue将信息从一个进程传递到另一个进程。
| 归档时间: |
|
| 查看次数: |
56 次 |
| 最近记录: |