Python 使用多处理停止web2py中的长时间运行的操作

Python 使用多处理停止web2py中的长时间运行的操作,python,multithreading,session,web2py,kill-process,Python,Multithreading,Session,Web2py,Kill Process,我有一个web2py应用程序,基本上用作Python脚本的浏览器界面。此脚本通常返回得很快,但有时可能需要很长时间。我想为用户提供一种在脚本执行时间过长时停止脚本执行的方法 我当前调用的函数如下所示: def myView(): # this function is called from ajax session.model = myFunc() # myFunc is from a module which i have complete control over ret

我有一个web2py应用程序,基本上用作Python脚本的浏览器界面。此脚本通常返回得很快,但有时可能需要很长时间。我想为用户提供一种在脚本执行时间过长时停止脚本执行的方法

我当前调用的函数如下所示:

def myView():  # this function is called from ajax
    session.model = myFunc()  # myFunc is from a module which i have complete control over
    return dict(model=session.model)
myFunc
在使用某些选项调用时,会使用多处理,但最终仍会花费很长时间。我需要某种方法来终止函数,或者至少终止线程的子线程

我尝试的第一件事是在一个新进程中运行
myFunc
,然后滚动我自己的简单事件系统来杀死它:

# in the controller
def myView():
    p_conn, c_conn = multiprocessing.Pipe()
    events = multiprocessing.Manager().dict()
    proc = multiprocessing.Process(target=_fit, args=(options, events c_conn))
    proc.start()
    sleep(0.01)
    session.events = events
    proc.join()
    session.model = p_conn.recv()
    return dict(model=session.model)

def _fit(options, events pipe):
    pipe.send(fitting.logistic_fit(options=options, events=events))
    pipe.close()

def stop():
    try:
        session.events['kill']()
    except SystemExit:
        pass  # because it raises that error intentionally
    return dict()

# in the module
def kill():
    print multiprocessing.active_children()
    for p in multiprocessing.active_children():
        p.terminate()
    raise SystemExit

def myFunc(options, events):
    events['kill'] = kill
我在这方面遇到了几个主要问题

  • stop()
    中的会话并不总是与
    myView()
    中的会话相同,因此
    session.events
    为无
  • 即使会话是相同的,
    kill()
    也不能正确地杀死孩子
  • 长时间运行的函数将挂起web2py线程,因此直到函数完成后才处理
    stop()
  • 我考虑过以后不要调用
    join()
    并使用AJAX获取函数的结果,但我无法将流程对象保存在
    session
    中供以后使用。管道似乎可以进行酸洗,但随后我遇到了无法从另一个视图访问同一会话的问题


    如何实现此功能?

    对于长时间运行的任务,最好通过内置队列将其排队。如果要允许用户手动停止耗时过长的任务,可以使用
    调度程序.stop_task(ref)
    方法(其中
    ref
    是任务
    id
    uuid
    )。或者,当您对任务排队时,您可以指定一个超时,因此如果在超时时间内未完成任务,它将自动停止


    您可以执行简单的Ajax轮询,在任务完成时通知客户机(或者使用websockets或SSE实现更复杂的功能)。

    您能详细介绍一下您的答案吗?一些值得回答的具体问题:调度器是否立即从脚本启动任务?如何获得任务的结果?如何强制停止任务?事实上,这并不能完全回答这个问题。我已经更新了答案来回答你的最后一个问题。您的前两个问题将在链接文档中解决。由于它们涉及一般的调度程序功能,并且不是您原始问题的一部分,因此我不会更新答案,但我将简要说明,默认情况下,新任务会立即排队(您可以通过设置
    immediate=True
    )和
    调度程序.task_status()
    方法用于检索结果。