【问题标题】:python endpoint starting a thread with lockingpython端点启动一个带锁定的线程
【发布时间】:2021-04-21 09:52:53
【问题描述】:

我正在使用 FASTApi 并尝试实现一个端点,它启动了一项工作。一旦作业开始,端点将被“锁定”直到前一个作业完成。到目前为止,它是这样实现的:

myapp.lock = threading.Lock()

@myapp.get("/jobs")
def start_job(some_args):
    if myapp.lock.acquire(False):
        th = threading.Thread(target=job,kwargs=some_args)
        th.start()
        return "Job started"
    else:
        raise HTTPException(status_code=400,detail="Job already running.")

所以,当job开始时,会使用job方法创建一个线程:

def job(some_args):
    try:
        #doing some stuff, creating objects and writing to files
    finally:
        myapp.lock.release()

到目前为止一切顺利,端点正在工作,启动作业并在作业运行时锁定。 但我的问题是,尽管工作“完成”并释放了锁,但线程仍然存在。我希望线程在执行后会自行关闭。也许问题是 myapp 让它保持活力?我怎样才能阻止它?

【问题讨论】:

  • 您不能在异步应用程序中使用阻塞同步方法。我建议将任务的状态存储在一个全局对象中(除非您使用多个工作人员)。并检查它而不是挂在锁里。也许这里的一个例子对你有用。 stackoverflow.com/questions/63169865/…
  • 感谢@alex_noname,我找到了解决方案。对我来说最简单的方法是使用 FastAPI 中的 BackgroundTasks。
  • @alex_noname 因为这是一个同步视图,FastAPI 会自动为其启动一个单独的线程,所以在这种情况下这不是问题(视图本身不会阻塞异步循环)
  • @hellothere 考虑发布您的解决方案作为此问题的答案,因为它可以帮助遇到相同问题的任何人。

标签: python multithreading fastapi


【解决方案1】:

我想出了这种解决方案:

myapp.lock = False

@myapp.get("/jobs")
async def start_job(some_args, background_tasks: BackgroundTasks):
    if not myapp.lock:
        background_tasks.add_task(job, some_args)
        return "Job started"
    else:
        raise HTTPException(status_code=400,detail="Job already running.")

def job(some_args):
    try:
        myapp.lock = True
        #doing some stuff, creating objects and writing to files
    finally:
        myapp.lock = False

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多